diff options
| -rw-r--r-- | lisp/progmodes/cc-align.el | 392 | ||||
| -rw-r--r-- | lisp/progmodes/cc-cmds.el | 1369 | ||||
| -rw-r--r-- | lisp/progmodes/cc-compat.el | 149 | ||||
| -rw-r--r-- | lisp/progmodes/cc-defs.el | 185 | ||||
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 1704 | ||||
| -rw-r--r-- | lisp/progmodes/cc-langs.el | 551 | ||||
| -rw-r--r-- | lisp/progmodes/cc-menus.el | 103 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 344 | ||||
| -rw-r--r-- | lisp/progmodes/cc-styles.el | 617 | ||||
| -rw-r--r-- | lisp/progmodes/cc-vars.el | 391 |
10 files changed, 5805 insertions, 0 deletions
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el new file mode 100644 index 00000000000..3902e1efc4a --- /dev/null +++ b/lisp/progmodes/cc-align.el | |||
| @@ -0,0 +1,392 @@ | |||
| 1 | ;;; cc-align.el --- custom indentation functions for 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.12 | ||
| 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 | (require 'cc-defs) | ||
| 32 | (require 'cc-vars) | ||
| 33 | (require 'cc-engine) | ||
| 34 | (require 'cc-langs)) | ||
| 35 | |||
| 36 | |||
| 37 | ;; Standard indentation line-ups | ||
| 38 | (defun c-lineup-arglist (langelem) | ||
| 39 | ;; lineup the current arglist line with the arglist appearing just | ||
| 40 | ;; after the containing paren which starts the arglist. | ||
| 41 | (save-excursion | ||
| 42 | (let* ((containing-sexp | ||
| 43 | (save-excursion | ||
| 44 | ;; arglist-cont-nonempty gives relpos == | ||
| 45 | ;; to boi of containing-sexp paren. This | ||
| 46 | ;; is good when offset is +, but bad | ||
| 47 | ;; when it is c-lineup-arglist, so we | ||
| 48 | ;; have to special case a kludge here. | ||
| 49 | (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty)) | ||
| 50 | (progn | ||
| 51 | (beginning-of-line) | ||
| 52 | (backward-up-list 1) | ||
| 53 | (skip-chars-forward " \t" (c-point 'eol))) | ||
| 54 | (goto-char (cdr langelem))) | ||
| 55 | (point))) | ||
| 56 | (langelem-col (c-langelem-col langelem t))) | ||
| 57 | (if (save-excursion | ||
| 58 | (beginning-of-line) | ||
| 59 | (looking-at "[ \t]*)")) | ||
| 60 | (progn (goto-char (match-end 0)) | ||
| 61 | (forward-sexp -1) | ||
| 62 | (forward-char 1) | ||
| 63 | (c-forward-syntactic-ws) | ||
| 64 | (- (current-column) langelem-col)) | ||
| 65 | (goto-char containing-sexp) | ||
| 66 | (or (eolp) | ||
| 67 | (not (memq (char-after) '(?{ ?\( ))) | ||
| 68 | (let ((eol (c-point 'eol)) | ||
| 69 | (here (progn | ||
| 70 | (forward-char 1) | ||
| 71 | (skip-chars-forward " \t") | ||
| 72 | (point)))) | ||
| 73 | (c-forward-syntactic-ws) | ||
| 74 | (if (< (point) eol) | ||
| 75 | (goto-char here)))) | ||
| 76 | (- (current-column) langelem-col) | ||
| 77 | )))) | ||
| 78 | |||
| 79 | (defun c-lineup-arglist-intro-after-paren (langelem) | ||
| 80 | ;; lineup an arglist-intro line to just after the open paren | ||
| 81 | (save-excursion | ||
| 82 | (let ((langelem-col (c-langelem-col langelem t)) | ||
| 83 | (ce-curcol (save-excursion | ||
| 84 | (beginning-of-line) | ||
| 85 | (backward-up-list 1) | ||
| 86 | (skip-chars-forward " \t" (c-point 'eol)) | ||
| 87 | (current-column)))) | ||
| 88 | (- ce-curcol langelem-col -1)))) | ||
| 89 | |||
| 90 | (defun c-lineup-arglist-close-under-paren (langelem) | ||
| 91 | ;; lineup an arglist-intro line to just after the open paren | ||
| 92 | (save-excursion | ||
| 93 | (let ((langelem-col (c-langelem-col langelem t)) | ||
| 94 | (ce-curcol (save-excursion | ||
| 95 | (beginning-of-line) | ||
| 96 | (backward-up-list 1) | ||
| 97 | (current-column)))) | ||
| 98 | (- ce-curcol langelem-col)))) | ||
| 99 | |||
| 100 | (defun c-lineup-streamop (langelem) | ||
| 101 | ;; lineup stream operators | ||
| 102 | (save-excursion | ||
| 103 | (let ((langelem-col (c-langelem-col langelem))) | ||
| 104 | (re-search-forward "<<\\|>>" (c-point 'eol) 'move) | ||
| 105 | (goto-char (match-beginning 0)) | ||
| 106 | (- (current-column) langelem-col)))) | ||
| 107 | |||
| 108 | (defun c-lineup-multi-inher (langelem) | ||
| 109 | ;; line up multiple inheritance lines | ||
| 110 | (save-excursion | ||
| 111 | (let ((eol (c-point 'eol)) | ||
| 112 | (here (point)) | ||
| 113 | (langelem-col (c-langelem-col langelem))) | ||
| 114 | (skip-chars-forward "^:" eol) | ||
| 115 | (skip-chars-forward " \t:" eol) | ||
| 116 | (if (or (eolp) | ||
| 117 | (looking-at c-comment-start-regexp)) | ||
| 118 | (c-forward-syntactic-ws here)) | ||
| 119 | (- (current-column) langelem-col) | ||
| 120 | ))) | ||
| 121 | |||
| 122 | (defun c-lineup-java-inher (langelem) | ||
| 123 | ;; line up Java implements and extends continuations | ||
| 124 | (save-excursion | ||
| 125 | (let ((langelem-col (c-langelem-col langelem))) | ||
| 126 | (forward-word 1) | ||
| 127 | (if (looking-at "[ \t]*$") | ||
| 128 | langelem-col | ||
| 129 | (c-forward-syntactic-ws) | ||
| 130 | (- (current-column) langelem-col))))) | ||
| 131 | |||
| 132 | (defun c-lineup-java-throws (langelem) | ||
| 133 | ;; lineup func-decl-cont's in Java which are continuations of throws | ||
| 134 | ;; declarations. If `throws' starts the previous line, line up to | ||
| 135 | ;; just after that keyword. If not, lineup under the previous line. | ||
| 136 | (save-excursion | ||
| 137 | (let ((iopl (c-point 'iopl)) | ||
| 138 | (langelem-col (c-langelem-col langelem t)) | ||
| 139 | (extra 0)) | ||
| 140 | (back-to-indentation) | ||
| 141 | (cond | ||
| 142 | ((looking-at "throws[ \t\n]") | ||
| 143 | (goto-char (cdr langelem)) | ||
| 144 | (setq extra c-basic-offset)) | ||
| 145 | ((and (goto-char iopl) | ||
| 146 | (looking-at "throws[ \t\n]")) | ||
| 147 | (forward-word 1) | ||
| 148 | (skip-chars-forward " \t") | ||
| 149 | (when (eolp) | ||
| 150 | (back-to-indentation) | ||
| 151 | (setq extra c-basic-offset))) | ||
| 152 | (t (goto-char iopl))) | ||
| 153 | (+ (- (current-column) langelem-col) extra)))) | ||
| 154 | |||
| 155 | (defun c-lineup-C-comments (langelem) | ||
| 156 | ;; line up C block comment continuation lines | ||
| 157 | (save-excursion | ||
| 158 | (let ((here (point)) | ||
| 159 | (stars (progn (back-to-indentation) | ||
| 160 | (skip-chars-forward "*"))) | ||
| 161 | (langelem-col (c-langelem-col langelem))) | ||
| 162 | (back-to-indentation) | ||
| 163 | (if (not (re-search-forward "/\\([*]+\\)" (c-point 'eol) t)) | ||
| 164 | (progn | ||
| 165 | (if (not (looking-at "[*]+")) | ||
| 166 | (progn | ||
| 167 | ;; we now have to figure out where this comment begins. | ||
| 168 | (goto-char here) | ||
| 169 | (back-to-indentation) | ||
| 170 | (if (looking-at "[*]+/") | ||
| 171 | (progn (goto-char (match-end 0)) | ||
| 172 | (forward-comment -1)) | ||
| 173 | (goto-char (cdr langelem)) | ||
| 174 | (back-to-indentation)))) | ||
| 175 | (- (current-column) langelem-col)) | ||
| 176 | (if (zerop stars) | ||
| 177 | (progn | ||
| 178 | (skip-chars-forward " \t") | ||
| 179 | (- (current-column) langelem-col)) | ||
| 180 | ;; how many stars on comment opening line? if greater than | ||
| 181 | ;; on current line, align left. if less than or equal, | ||
| 182 | ;; align right. this should also pick up Javadoc style | ||
| 183 | ;; comments. | ||
| 184 | (if (> (length (match-string 1)) stars) | ||
| 185 | (progn | ||
| 186 | (back-to-indentation) | ||
| 187 | (- (current-column) -1 langelem-col)) | ||
| 188 | (- (current-column) stars langelem-col)) | ||
| 189 | ))))) | ||
| 190 | |||
| 191 | (defun c-lineup-comment (langelem) | ||
| 192 | ;; support old behavior for comment indentation. we look at | ||
| 193 | ;; c-comment-only-line-offset to decide how to indent comment | ||
| 194 | ;; only-lines | ||
| 195 | (save-excursion | ||
| 196 | (back-to-indentation) | ||
| 197 | ;; this highly kludgiforous flag prevents the mapcar over | ||
| 198 | ;; c-syntactic-context from entering an infinite loop | ||
| 199 | (let ((recurse-prevention-flag (boundp 'recurse-prevention-flag))) | ||
| 200 | (cond | ||
| 201 | ;; CASE 1: preserve comment-column | ||
| 202 | (recurse-prevention-flag 0) | ||
| 203 | ((= (current-column) comment-column) | ||
| 204 | ;; we have to subtract out all other indentation | ||
| 205 | (- comment-column (apply '+ (mapcar 'c-get-offset | ||
| 206 | c-syntactic-context)))) | ||
| 207 | ;; indent as specified by c-comment-only-line-offset | ||
| 208 | ((not (bolp)) | ||
| 209 | (or (car-safe c-comment-only-line-offset) | ||
| 210 | c-comment-only-line-offset)) | ||
| 211 | (t | ||
| 212 | (or (cdr-safe c-comment-only-line-offset) | ||
| 213 | (car-safe c-comment-only-line-offset) | ||
| 214 | -1000)) ;jam it against the left side | ||
| 215 | )))) | ||
| 216 | |||
| 217 | (defun c-lineup-runin-statements (langelem) | ||
| 218 | ;; line up statements in coding standards which place the first | ||
| 219 | ;; statement on the same line as the block opening brace. | ||
| 220 | (if (eq (char-after (cdr langelem)) ?{) | ||
| 221 | (save-excursion | ||
| 222 | (let ((langelem-col (c-langelem-col langelem))) | ||
| 223 | (forward-char 1) | ||
| 224 | (skip-chars-forward " \t") | ||
| 225 | (- (current-column) langelem-col))) | ||
| 226 | 0)) | ||
| 227 | |||
| 228 | (defun c-lineup-math (langelem) | ||
| 229 | ;; line up math statement-cont after the equals | ||
| 230 | (save-excursion | ||
| 231 | (let ((equalp (save-excursion | ||
| 232 | (goto-char (c-point 'boi)) | ||
| 233 | (skip-chars-forward "^=" (c-point 'eol)) | ||
| 234 | (and (eq (char-after) ?=) | ||
| 235 | (- (point) (c-point 'boi))))) | ||
| 236 | (langelem-col (c-langelem-col langelem)) | ||
| 237 | donep) | ||
| 238 | (while (and (not donep) | ||
| 239 | (< (point) (c-point 'eol))) | ||
| 240 | (skip-chars-forward "^=" (c-point 'eol)) | ||
| 241 | (if (c-in-literal (cdr langelem)) | ||
| 242 | (forward-char 1) | ||
| 243 | (setq donep t))) | ||
| 244 | (if (not (eq (char-after) ?=)) | ||
| 245 | ;; there's no equal sign on the line | ||
| 246 | c-basic-offset | ||
| 247 | ;; calculate indentation column after equals and ws, unless | ||
| 248 | ;; our line contains an equals sign | ||
| 249 | (if (not equalp) | ||
| 250 | (progn | ||
| 251 | (forward-char 1) | ||
| 252 | (skip-chars-forward " \t") | ||
| 253 | (setq equalp 0))) | ||
| 254 | (- (current-column) equalp langelem-col)) | ||
| 255 | ))) | ||
| 256 | |||
| 257 | (defun c-lineup-ObjC-method-call (langelem) | ||
| 258 | ;; Line up methods args as elisp-mode does with function args: go to | ||
| 259 | ;; the position right after the message receiver, and if you are at | ||
| 260 | ;; (eolp) indent the current line by a constant offset from the | ||
| 261 | ;; opening bracket; otherwise we are looking at the first character | ||
| 262 | ;; of the first method call argument, so lineup the current line | ||
| 263 | ;; with it. | ||
| 264 | (save-excursion | ||
| 265 | (let* ((extra (save-excursion | ||
| 266 | (back-to-indentation) | ||
| 267 | (c-backward-syntactic-ws (cdr langelem)) | ||
| 268 | (if (eq (char-before) ?:) | ||
| 269 | (- c-basic-offset) | ||
| 270 | 0))) | ||
| 271 | (open-bracket-pos (cdr langelem)) | ||
| 272 | (open-bracket-col (progn | ||
| 273 | (goto-char open-bracket-pos) | ||
| 274 | (current-column))) | ||
| 275 | (target-col (progn | ||
| 276 | (forward-char) | ||
| 277 | (forward-sexp) | ||
| 278 | (skip-chars-forward " \t") | ||
| 279 | (if (eolp) | ||
| 280 | (+ open-bracket-col c-basic-offset) | ||
| 281 | (current-column)))) | ||
| 282 | ) | ||
| 283 | (- target-col open-bracket-col extra)))) | ||
| 284 | |||
| 285 | (defun c-lineup-ObjC-method-args (langelem) | ||
| 286 | ;; Line up the colons that separate args. This is done trying to | ||
| 287 | ;; align colons vertically. | ||
| 288 | (save-excursion | ||
| 289 | (let* ((here (c-point 'boi)) | ||
| 290 | (curcol (progn (goto-char here) (current-column))) | ||
| 291 | (eol (c-point 'eol)) | ||
| 292 | (relpos (cdr langelem)) | ||
| 293 | (first-col-column (progn | ||
| 294 | (goto-char relpos) | ||
| 295 | (skip-chars-forward "^:" eol) | ||
| 296 | (and (eq (char-after) ?:) | ||
| 297 | (current-column))))) | ||
| 298 | (if (not first-col-column) | ||
| 299 | c-basic-offset | ||
| 300 | (goto-char here) | ||
| 301 | (skip-chars-forward "^:" eol) | ||
| 302 | (if (eq (char-after) ?:) | ||
| 303 | (+ curcol (- first-col-column (current-column))) | ||
| 304 | c-basic-offset))))) | ||
| 305 | |||
| 306 | (defun c-lineup-ObjC-method-args-2 (langelem) | ||
| 307 | ;; Line up the colons that separate args. This is done trying to | ||
| 308 | ;; align the colon on the current line with the previous one. | ||
| 309 | (save-excursion | ||
| 310 | (let* ((here (c-point 'boi)) | ||
| 311 | (curcol (progn (goto-char here) (current-column))) | ||
| 312 | (eol (c-point 'eol)) | ||
| 313 | (relpos (cdr langelem)) | ||
| 314 | (prev-col-column (progn | ||
| 315 | (skip-chars-backward "^:" relpos) | ||
| 316 | (and (eq (char-before) ?:) | ||
| 317 | (- (current-column) 1))))) | ||
| 318 | (if (not prev-col-column) | ||
| 319 | c-basic-offset | ||
| 320 | (goto-char here) | ||
| 321 | (skip-chars-forward "^:" eol) | ||
| 322 | (if (eq (char-after) ?:) | ||
| 323 | (+ curcol (- prev-col-column (current-column))) | ||
| 324 | c-basic-offset))))) | ||
| 325 | |||
| 326 | (defun c-snug-do-while (syntax pos) | ||
| 327 | "Dynamically calculate brace hanginess for do-while statements. | ||
| 328 | Using this function, `while' clauses that end a `do-while' block will | ||
| 329 | remain on the same line as the brace that closes that block. | ||
| 330 | |||
| 331 | See `c-hanging-braces-alist' for how to utilize this function as an | ||
| 332 | ACTION associated with `block-close' syntax." | ||
| 333 | (save-excursion | ||
| 334 | (let (langelem) | ||
| 335 | (if (and (eq syntax 'block-close) | ||
| 336 | (setq langelem (assq 'block-close c-syntactic-context)) | ||
| 337 | (progn (goto-char (cdr langelem)) | ||
| 338 | (if (eq (char-after) ?{) | ||
| 339 | (c-safe (forward-sexp -1))) | ||
| 340 | (looking-at "\\<do\\>[^_]"))) | ||
| 341 | '(before) | ||
| 342 | '(before after))))) | ||
| 343 | |||
| 344 | (defun c-gnu-impose-minimum () | ||
| 345 | "Imposes a minimum indentation for lines inside a top-level construct. | ||
| 346 | The variable `c-label-minimum-indentation' specifies the minimum | ||
| 347 | indentation amount." | ||
| 348 | (let ((non-top-levels '(defun-block-intro statement statement-cont | ||
| 349 | statement-block-intro statement-case-intro | ||
| 350 | statement-case-open substatement substatement-open | ||
| 351 | case-label label do-while-closure else-clause | ||
| 352 | )) | ||
| 353 | (syntax c-syntactic-context) | ||
| 354 | langelem) | ||
| 355 | (while syntax | ||
| 356 | (setq langelem (car (car syntax)) | ||
| 357 | syntax (cdr syntax)) | ||
| 358 | ;; don't adjust comment-only lines | ||
| 359 | (cond ((eq langelem 'comment-intro) | ||
| 360 | (setq syntax nil)) | ||
| 361 | ((memq langelem non-top-levels) | ||
| 362 | (save-excursion | ||
| 363 | (setq syntax nil) | ||
| 364 | (back-to-indentation) | ||
| 365 | (if (zerop (current-column)) | ||
| 366 | (insert (make-string c-label-minimum-indentation 32))) | ||
| 367 | )) | ||
| 368 | )))) | ||
| 369 | |||
| 370 | |||
| 371 | ;; Useful for c-hanging-semi&comma-criteria | ||
| 372 | (defun c-semi&comma-inside-parenlist () | ||
| 373 | "Determine if a newline should be added after a semicolon. | ||
| 374 | If a comma was inserted, no determination is made. If a semicolon was | ||
| 375 | inserted inside a parenthesis list, no newline is added otherwise a | ||
| 376 | newline is added. In either case, checking is stopped. This supports | ||
| 377 | exactly the old newline insertion behavior." | ||
| 378 | ;; newline only after semicolon, but only if that semicolon is not | ||
| 379 | ;; inside a parenthesis list (e.g. a for loop statement) | ||
| 380 | (if (not (eq last-command-char ?\;)) | ||
| 381 | nil ; continue checking | ||
| 382 | (if (condition-case nil | ||
| 383 | (save-excursion | ||
| 384 | (up-list -1) | ||
| 385 | (not (eq (char-after) ?\())) | ||
| 386 | (error t)) | ||
| 387 | t | ||
| 388 | 'stop))) | ||
| 389 | |||
| 390 | |||
| 391 | (provide 'cc-align) | ||
| 392 | ;;; cc-align.el ends here | ||
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el new file mode 100644 index 00000000000..62e89522bbb --- /dev/null +++ b/lisp/progmodes/cc-cmds.el | |||
| @@ -0,0 +1,1369 @@ | |||
| 1 | ;;; cc-cmds.el --- user level commands for 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.12 | ||
| 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 | (defun c-calculate-state (arg prevstate) | ||
| 32 | ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If | ||
| 33 | ;; arg is nil or zero, toggle the state. If arg is negative, turn | ||
| 34 | ;; the state off, and if arg is positive, turn the state on | ||
| 35 | (if (or (not arg) | ||
| 36 | (zerop (setq arg (prefix-numeric-value arg)))) | ||
| 37 | (not prevstate) | ||
| 38 | (> arg 0))) | ||
| 39 | |||
| 40 | ;; Auto-newline and hungry-delete | ||
| 41 | (defun c-toggle-auto-state (arg) | ||
| 42 | "Toggle auto-newline feature. | ||
| 43 | Optional numeric ARG, if supplied turns on auto-newline when positive, | ||
| 44 | turns it off when negative, and just toggles it when zero. | ||
| 45 | |||
| 46 | When the auto-newline feature is enabled (as evidenced by the `/a' or | ||
| 47 | `/ah' on the modeline after the mode name) newlines are automatically | ||
| 48 | inserted after special characters such as brace, comma, semi-colon, | ||
| 49 | and colon." | ||
| 50 | (interactive "P") | ||
| 51 | (setq c-auto-newline (c-calculate-state arg c-auto-newline)) | ||
| 52 | (c-update-modeline) | ||
| 53 | (c-keep-region-active)) | ||
| 54 | |||
| 55 | (defun c-toggle-hungry-state (arg) | ||
| 56 | "Toggle hungry-delete-key feature. | ||
| 57 | Optional numeric ARG, if supplied turns on hungry-delete when positive, | ||
| 58 | turns it off when negative, and just toggles it when zero. | ||
| 59 | |||
| 60 | When the hungry-delete-key feature is enabled (as evidenced by the | ||
| 61 | `/h' or `/ah' on the modeline after the mode name) the delete key | ||
| 62 | gobbles all preceding whitespace in one fell swoop." | ||
| 63 | (interactive "P") | ||
| 64 | (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key)) | ||
| 65 | (c-update-modeline) | ||
| 66 | (c-keep-region-active)) | ||
| 67 | |||
| 68 | (defun c-toggle-auto-hungry-state (arg) | ||
| 69 | "Toggle auto-newline and hungry-delete-key features. | ||
| 70 | Optional numeric ARG, if supplied turns on auto-newline and | ||
| 71 | hungry-delete when positive, turns them off when negative, and just | ||
| 72 | toggles them when zero. | ||
| 73 | |||
| 74 | See `c-toggle-auto-state' and `c-toggle-hungry-state' for details." | ||
| 75 | (interactive "P") | ||
| 76 | (setq c-auto-newline (c-calculate-state arg c-auto-newline)) | ||
| 77 | (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key)) | ||
| 78 | (c-update-modeline) | ||
| 79 | (c-keep-region-active)) | ||
| 80 | |||
| 81 | |||
| 82 | ;; Electric keys | ||
| 83 | |||
| 84 | ;; Note: In XEmacs 20.3 the Delete and BackSpace keysyms have been | ||
| 85 | ;; separated and "\177" is no longer an alias for both keys. Also, | ||
| 86 | ;; the variable delete-key-deletes-forward controls in which direction | ||
| 87 | ;; the Delete keysym deletes characters. The functions | ||
| 88 | ;; c-electric-delete and c-electric-backspace attempt to deal with | ||
| 89 | ;; this new functionality. For Emacs 19 and XEmacs 19 backwards | ||
| 90 | ;; compatibility, the old behavior has moved to c-electric-backspace | ||
| 91 | ;; and c-backspace-function. | ||
| 92 | |||
| 93 | (defun c-electric-backspace (arg) | ||
| 94 | "Deletes preceding character or whitespace. | ||
| 95 | If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or | ||
| 96 | \"/ah\" string on the mode line, then all preceding whitespace is | ||
| 97 | consumed. If however an ARG is supplied, or `c-hungry-delete-key' is | ||
| 98 | nil, or point is inside a literal then the function in the variable | ||
| 99 | `c-backspace-function' is called. | ||
| 100 | |||
| 101 | See also \\[c-electric-delete]." | ||
| 102 | (interactive "P") | ||
| 103 | (if (or (not c-hungry-delete-key) | ||
| 104 | arg | ||
| 105 | (c-in-literal)) | ||
| 106 | (funcall c-backspace-function (prefix-numeric-value arg)) | ||
| 107 | (let ((here (point))) | ||
| 108 | (skip-chars-backward " \t\n") | ||
| 109 | (if (/= (point) here) | ||
| 110 | (delete-region (point) here) | ||
| 111 | (funcall c-backspace-function 1) | ||
| 112 | )))) | ||
| 113 | |||
| 114 | (defun c-electric-delete (arg) | ||
| 115 | "Deletes preceding or following character or whitespace. | ||
| 116 | |||
| 117 | The behavior of this function depends on the variable | ||
| 118 | `delete-key-deletes-forward'. If this variable is nil (or does not | ||
| 119 | exist, as in older Emacsen), then this function behaves identical to | ||
| 120 | \\[c-electric-backspace]. | ||
| 121 | |||
| 122 | If `delete-key-deletes-forward' is non-nil, then deletion occurs in | ||
| 123 | the forward direction. So if `c-hungry-delete-key' is non-nil, as | ||
| 124 | evidenced by the \"/h\" or \"/ah\" string on the mode line, then all | ||
| 125 | following whitespace is consumed. If however an ARG is supplied, or | ||
| 126 | `c-hungry-delete-key' is nil, or point is inside a literal then the | ||
| 127 | function in the variable `c-delete-function' is called." | ||
| 128 | (interactive "P") | ||
| 129 | (if (and (boundp 'delete-key-deletes-forward) | ||
| 130 | delete-key-deletes-forward) | ||
| 131 | (if (or (not c-hungry-delete-key) | ||
| 132 | arg | ||
| 133 | (c-in-literal)) | ||
| 134 | (funcall c-delete-function (prefix-numeric-value arg)) | ||
| 135 | (let ((here (point))) | ||
| 136 | (skip-chars-forward " \t\n") | ||
| 137 | (if (/= (point) here) | ||
| 138 | (delete-region (point) here) | ||
| 139 | (funcall c-delete-function 1)))) | ||
| 140 | ;; act just like c-electric-backspace | ||
| 141 | (c-electric-backspace arg))) | ||
| 142 | |||
| 143 | (defun c-electric-pound (arg) | ||
| 144 | "Electric pound (`#') insertion. | ||
| 145 | Inserts a `#' character specially depending on the variable | ||
| 146 | `c-electric-pound-behavior'. If a numeric ARG is supplied, or if | ||
| 147 | point is inside a literal, nothing special happens." | ||
| 148 | (interactive "P") | ||
| 149 | (if (or (c-in-literal) | ||
| 150 | arg | ||
| 151 | (not (memq 'alignleft c-electric-pound-behavior))) | ||
| 152 | ;; do nothing special | ||
| 153 | (self-insert-command (prefix-numeric-value arg)) | ||
| 154 | ;; place the pound character at the left edge | ||
| 155 | (let ((pos (- (point-max) (point))) | ||
| 156 | (bolp (bolp))) | ||
| 157 | (beginning-of-line) | ||
| 158 | (delete-horizontal-space) | ||
| 159 | (insert-char last-command-char 1) | ||
| 160 | (and (not bolp) | ||
| 161 | (goto-char (- (point-max) pos))) | ||
| 162 | ))) | ||
| 163 | |||
| 164 | (defun c-electric-brace (arg) | ||
| 165 | "Insert a brace. | ||
| 166 | |||
| 167 | If the auto-newline feature is turned on, as evidenced by the \"/a\" | ||
| 168 | or \"/ah\" string on the mode line, newlines are inserted before and | ||
| 169 | after braces based on the value of `c-hanging-braces-alist'. | ||
| 170 | |||
| 171 | Also, the line is re-indented unless a numeric ARG is supplied, there | ||
| 172 | are non-whitespace characters present on the line after the brace, or | ||
| 173 | the brace is inserted inside a literal." | ||
| 174 | (interactive "P") | ||
| 175 | (let* ((c-state-cache (c-parse-state)) | ||
| 176 | (safepos (c-safe-position (point) c-state-cache)) | ||
| 177 | (literal (c-in-literal safepos))) | ||
| 178 | ;; if we're in a literal, or we're not at the end of the line, or | ||
| 179 | ;; a numeric arg is provided, or auto-newlining is turned off, | ||
| 180 | ;; then just insert the character. | ||
| 181 | (if (or literal arg | ||
| 182 | ; (not c-auto-newline) | ||
| 183 | (not (looking-at "[ \t]*$"))) | ||
| 184 | (self-insert-command (prefix-numeric-value arg)) | ||
| 185 | (let* ((syms '(class-open class-close defun-open defun-close | ||
| 186 | inline-open inline-close brace-list-open brace-list-close | ||
| 187 | brace-list-intro brace-list-entry block-open block-close | ||
| 188 | substatement-open statement-case-open | ||
| 189 | extern-lang-open extern-lang-close)) | ||
| 190 | ;; we want to inhibit blinking the paren since this will | ||
| 191 | ;; be most disruptive. we'll blink it ourselves later on | ||
| 192 | (old-blink-paren blink-paren-function) | ||
| 193 | blink-paren-function | ||
| 194 | (insertion-point (point)) | ||
| 195 | delete-temp-newline | ||
| 196 | (preserve-p (eq 32 (char-syntax (char-before)))) | ||
| 197 | ;; shut this up too | ||
| 198 | (c-echo-syntactic-information-p nil) | ||
| 199 | (syntax (progn | ||
| 200 | ;; only insert a newline if there is | ||
| 201 | ;; non-whitespace behind us | ||
| 202 | (if (save-excursion | ||
| 203 | (skip-chars-backward " \t") | ||
| 204 | (not (bolp))) | ||
| 205 | (progn (newline) | ||
| 206 | (setq delete-temp-newline t))) | ||
| 207 | (self-insert-command (prefix-numeric-value arg)) | ||
| 208 | ;; state cache doesn't change | ||
| 209 | (c-guess-basic-syntax))) | ||
| 210 | (newlines (and | ||
| 211 | c-auto-newline | ||
| 212 | (or (c-lookup-lists syms syntax c-hanging-braces-alist) | ||
| 213 | '(ignore before after))))) | ||
| 214 | ;; If syntax is a function symbol, then call it using the | ||
| 215 | ;; defined semantics. | ||
| 216 | (if (and (not (consp (cdr newlines))) | ||
| 217 | (functionp (cdr newlines))) | ||
| 218 | (let ((c-syntactic-context syntax)) | ||
| 219 | (setq newlines | ||
| 220 | (funcall (cdr newlines) (car newlines) insertion-point)))) | ||
| 221 | ;; does a newline go before the open brace? | ||
| 222 | (if (memq 'before newlines) | ||
| 223 | ;; we leave the newline we've put in there before, | ||
| 224 | ;; but we need to re-indent the line above | ||
| 225 | (let ((pos (- (point-max) (point))) | ||
| 226 | (here (point)) | ||
| 227 | (c-state-cache c-state-cache)) | ||
| 228 | (forward-line -1) | ||
| 229 | ;; we may need to update the cache. this should still be | ||
| 230 | ;; faster than recalculating the state in many cases | ||
| 231 | (save-excursion | ||
| 232 | (save-restriction | ||
| 233 | (narrow-to-region here (point)) | ||
| 234 | (if (and (c-safe (progn (backward-up-list -1) t)) | ||
| 235 | (memq (char-before) '(?\) ?})) | ||
| 236 | (progn (widen) | ||
| 237 | (c-safe (progn (forward-sexp -1) t)))) | ||
| 238 | (setq c-state-cache | ||
| 239 | (c-hack-state (point) 'open c-state-cache)) | ||
| 240 | (if (and (car c-state-cache) | ||
| 241 | (not (consp (car c-state-cache))) | ||
| 242 | (<= (point) (car c-state-cache))) | ||
| 243 | (setq c-state-cache (cdr c-state-cache)) | ||
| 244 | )))) | ||
| 245 | (let ((here (point)) | ||
| 246 | (shift (c-indent-line))) | ||
| 247 | (setq c-state-cache (c-adjust-state (c-point 'bol) here | ||
| 248 | (- shift) c-state-cache))) | ||
| 249 | (goto-char (- (point-max) pos)) | ||
| 250 | ;; if the buffer has changed due to the indentation, we | ||
| 251 | ;; need to recalculate syntax for the current line, but | ||
| 252 | ;; we won't need to update the state cache. | ||
| 253 | (if (/= (point) here) | ||
| 254 | (setq syntax (c-guess-basic-syntax)))) | ||
| 255 | ;; must remove the newline we just stuck in (if we really did it) | ||
| 256 | (and delete-temp-newline | ||
| 257 | (save-excursion | ||
| 258 | ;; if there is whitespace before point, then preserve | ||
| 259 | ;; at least one space. | ||
| 260 | (delete-indentation) | ||
| 261 | (just-one-space) | ||
| 262 | (if (not preserve-p) | ||
| 263 | (delete-char -1)))) | ||
| 264 | ;; since we're hanging the brace, we need to recalculate | ||
| 265 | ;; syntax. Update the state to accurately reflect the | ||
| 266 | ;; beginning of the line. We punt if we cross any open or | ||
| 267 | ;; closed parens because its just too hard to modify the | ||
| 268 | ;; known state. This limitation will be fixed in v5. | ||
| 269 | (save-excursion | ||
| 270 | (let ((bol (c-point 'bol))) | ||
| 271 | (if (zerop (car (parse-partial-sexp bol (1- (point))))) | ||
| 272 | (setq c-state-cache (c-whack-state bol c-state-cache) | ||
| 273 | syntax (c-guess-basic-syntax)) | ||
| 274 | ;; gotta punt. this requires some horrible kludgery | ||
| 275 | (beginning-of-line) | ||
| 276 | (makunbound 'c-state-cache) | ||
| 277 | (setq c-state-cache (c-parse-state) | ||
| 278 | syntax nil)))) | ||
| 279 | ) | ||
| 280 | ;; now adjust the line's indentation. don't update the state | ||
| 281 | ;; cache since c-guess-basic-syntax isn't called when the | ||
| 282 | ;; syntax is passed to c-indent-line | ||
| 283 | (let ((here (point)) | ||
| 284 | (shift (c-indent-line syntax))) | ||
| 285 | (setq c-state-cache (c-adjust-state (c-point 'bol) here | ||
| 286 | (- shift) c-state-cache))) | ||
| 287 | ;; Do all appropriate clean ups | ||
| 288 | (let ((here (point)) | ||
| 289 | (pos (- (point-max) (point))) | ||
| 290 | mbeg mend) | ||
| 291 | ;; clean up empty defun braces | ||
| 292 | (if (and c-auto-newline | ||
| 293 | (memq 'empty-defun-braces c-cleanup-list) | ||
| 294 | (eq last-command-char ?\}) | ||
| 295 | (c-intersect-lists '(defun-close class-close inline-close) | ||
| 296 | syntax) | ||
| 297 | (progn | ||
| 298 | (forward-char -1) | ||
| 299 | (skip-chars-backward " \t\n") | ||
| 300 | (eq (char-before) ?\{)) | ||
| 301 | ;; make sure matching open brace isn't in a comment | ||
| 302 | (not (c-in-literal))) | ||
| 303 | (delete-region (point) (1- here))) | ||
| 304 | ;; clean up brace-else-brace | ||
| 305 | (if (and c-auto-newline | ||
| 306 | (memq 'brace-else-brace c-cleanup-list) | ||
| 307 | (eq last-command-char ?\{) | ||
| 308 | (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t) | ||
| 309 | (progn | ||
| 310 | (setq mbeg (match-beginning 0) | ||
| 311 | mend (match-end 0)) | ||
| 312 | (= mend here)) | ||
| 313 | (not (c-in-literal))) | ||
| 314 | (progn | ||
| 315 | (delete-region mbeg mend) | ||
| 316 | (insert "} else {"))) | ||
| 317 | ;; clean up brace-elseif-brace | ||
| 318 | (if (and c-auto-newline | ||
| 319 | (memq 'brace-elseif-brace c-cleanup-list) | ||
| 320 | (eq last-command-char ?\{) | ||
| 321 | (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*" nil t) | ||
| 322 | (save-excursion | ||
| 323 | (goto-char (match-end 0)) | ||
| 324 | (c-safe (forward-sexp 1)) | ||
| 325 | (skip-chars-forward " \t\n") | ||
| 326 | (setq mbeg (match-beginning 0) | ||
| 327 | mend (match-end 0)) | ||
| 328 | (= here (1+ (point)))) | ||
| 329 | (not (c-in-literal))) | ||
| 330 | (progn | ||
| 331 | (delete-region mbeg mend) | ||
| 332 | (insert "} else if "))) | ||
| 333 | (goto-char (- (point-max) pos)) | ||
| 334 | ) | ||
| 335 | ;; does a newline go after the brace? | ||
| 336 | (if (memq 'after newlines) | ||
| 337 | (progn | ||
| 338 | (newline) | ||
| 339 | ;; update on c-state-cache | ||
| 340 | (let* ((bufpos (- (point) 2)) | ||
| 341 | (which (if (eq (char-after bufpos) ?{) 'open 'close)) | ||
| 342 | (c-state-cache (c-hack-state bufpos which c-state-cache))) | ||
| 343 | (c-indent-line)))) | ||
| 344 | ;; blink the paren | ||
| 345 | (and (eq last-command-char ?\}) | ||
| 346 | old-blink-paren | ||
| 347 | (save-excursion | ||
| 348 | (c-backward-syntactic-ws safepos) | ||
| 349 | (funcall old-blink-paren))) | ||
| 350 | )))) | ||
| 351 | |||
| 352 | (defun c-electric-slash (arg) | ||
| 353 | "Insert a slash character. | ||
| 354 | If slash is second of a double-slash C++ style comment introducing | ||
| 355 | construct, and we are on a comment-only-line, indent line as comment. | ||
| 356 | If numeric ARG is supplied or point is inside a literal, indentation | ||
| 357 | is inhibited." | ||
| 358 | (interactive "P") | ||
| 359 | (let ((indentp (and (not arg) | ||
| 360 | (eq (char-before) ?/) | ||
| 361 | (eq last-command-char ?/) | ||
| 362 | (not (c-in-literal)))) | ||
| 363 | ;; shut this up | ||
| 364 | (c-echo-syntactic-information-p nil)) | ||
| 365 | (self-insert-command (prefix-numeric-value arg)) | ||
| 366 | (if indentp | ||
| 367 | (c-indent-line)))) | ||
| 368 | |||
| 369 | (defun c-electric-star (arg) | ||
| 370 | "Insert a star character. | ||
| 371 | If the star is the second character of a C style comment introducing | ||
| 372 | construct, and we are on a comment-only-line, indent line as comment. | ||
| 373 | If numeric ARG is supplied or point is inside a literal, indentation | ||
| 374 | is inhibited." | ||
| 375 | (interactive "P") | ||
| 376 | (self-insert-command (prefix-numeric-value arg)) | ||
| 377 | ;; if we are in a literal, or if arg is given do not re-indent the | ||
| 378 | ;; current line, unless this star introduces a comment-only line. | ||
| 379 | (if (and (not arg) | ||
| 380 | (memq (c-in-literal) '(c)) | ||
| 381 | (eq (char-before) ?*) | ||
| 382 | (save-excursion | ||
| 383 | (forward-char -1) | ||
| 384 | (skip-chars-backward "*") | ||
| 385 | (if (eq (char-before) ?/) | ||
| 386 | (forward-char -1)) | ||
| 387 | (skip-chars-backward " \t") | ||
| 388 | (bolp))) | ||
| 389 | ;; shut this up | ||
| 390 | (let (c-echo-syntactic-information-p) | ||
| 391 | (c-indent-line)) | ||
| 392 | )) | ||
| 393 | |||
| 394 | (defun c-electric-semi&comma (arg) | ||
| 395 | "Insert a comma or semicolon. | ||
| 396 | When the auto-newline feature is turned on, as evidenced by the \"/a\" | ||
| 397 | or \"/ah\" string on the mode line, a newline might be inserted. See | ||
| 398 | the variable `c-hanging-semi&comma-criteria' for how newline insertion | ||
| 399 | is determined. | ||
| 400 | |||
| 401 | When semicolon is inserted, the line is re-indented unless a numeric | ||
| 402 | arg is supplied, point is inside a literal, or there are | ||
| 403 | non-whitespace characters on the line following the semicolon." | ||
| 404 | (interactive "P") | ||
| 405 | (let* ((lim (c-most-enclosing-brace (c-parse-state))) | ||
| 406 | (literal (c-in-literal lim)) | ||
| 407 | (here (point)) | ||
| 408 | ;; shut this up | ||
| 409 | (c-echo-syntactic-information-p nil)) | ||
| 410 | (if (or literal | ||
| 411 | arg | ||
| 412 | (not (looking-at "[ \t]*$"))) | ||
| 413 | (self-insert-command (prefix-numeric-value arg)) | ||
| 414 | ;; do some special stuff with the character | ||
| 415 | (self-insert-command (prefix-numeric-value arg)) | ||
| 416 | ;; do all cleanups, reindentations, and newline insertions, but | ||
| 417 | ;; only if c-auto-newline is turned on | ||
| 418 | (if (not c-auto-newline) nil | ||
| 419 | ;; clean ups | ||
| 420 | (let ((pos (- (point-max) (point)))) | ||
| 421 | (if (and (or (and | ||
| 422 | (eq last-command-char ?,) | ||
| 423 | (memq 'list-close-comma c-cleanup-list)) | ||
| 424 | (and | ||
| 425 | (eq last-command-char ?\;) | ||
| 426 | (memq 'defun-close-semi c-cleanup-list))) | ||
| 427 | (progn | ||
| 428 | (forward-char -1) | ||
| 429 | (skip-chars-backward " \t\n") | ||
| 430 | (eq (char-before) ?})) | ||
| 431 | ;; make sure matching open brace isn't in a comment | ||
| 432 | (not (c-in-literal lim))) | ||
| 433 | (delete-region (point) here)) | ||
| 434 | (goto-char (- (point-max) pos))) | ||
| 435 | ;; re-indent line | ||
| 436 | (c-indent-line) | ||
| 437 | ;; check to see if a newline should be added | ||
| 438 | (let ((criteria c-hanging-semi&comma-criteria) | ||
| 439 | answer add-newline-p) | ||
| 440 | (while criteria | ||
| 441 | (setq answer (funcall (car criteria))) | ||
| 442 | ;; only nil value means continue checking | ||
| 443 | (if (not answer) | ||
| 444 | (setq criteria (cdr criteria)) | ||
| 445 | (setq criteria nil) | ||
| 446 | ;; only 'stop specifically says do not add a newline | ||
| 447 | (setq add-newline-p (not (eq answer 'stop))) | ||
| 448 | )) | ||
| 449 | (if add-newline-p | ||
| 450 | (progn (newline) | ||
| 451 | (c-indent-line))) | ||
| 452 | ))))) | ||
| 453 | |||
| 454 | (defun c-electric-colon (arg) | ||
| 455 | "Insert a colon. | ||
| 456 | |||
| 457 | If the auto-newline feature is turned on, as evidenced by the \"/a\" | ||
| 458 | or \"/ah\" string on the mode line, newlines are inserted before and | ||
| 459 | after colons based on the value of `c-hanging-colons-alist'. | ||
| 460 | |||
| 461 | Also, the line is re-indented unless a numeric ARG is supplied, there | ||
| 462 | are non-whitespace characters present on the line after the colon, or | ||
| 463 | the colon is inserted inside a literal. | ||
| 464 | |||
| 465 | This function cleans up double colon scope operators based on the | ||
| 466 | value of `c-cleanup-list'." | ||
| 467 | (interactive "P") | ||
| 468 | (let* ((bod (c-point 'bod)) | ||
| 469 | (literal (c-in-literal bod)) | ||
| 470 | syntax newlines | ||
| 471 | ;; shut this up | ||
| 472 | (c-echo-syntactic-information-p nil)) | ||
| 473 | (if (or literal | ||
| 474 | arg | ||
| 475 | (not (looking-at "[ \t]*$"))) | ||
| 476 | (self-insert-command (prefix-numeric-value arg)) | ||
| 477 | ;; insert the colon, then do any specified cleanups | ||
| 478 | (self-insert-command (prefix-numeric-value arg)) | ||
| 479 | (let ((pos (- (point-max) (point))) | ||
| 480 | (here (point))) | ||
| 481 | (if (and c-auto-newline | ||
| 482 | (memq 'scope-operator c-cleanup-list) | ||
| 483 | (eq (char-before) ?:) | ||
| 484 | (progn | ||
| 485 | (forward-char -1) | ||
| 486 | (skip-chars-backward " \t\n") | ||
| 487 | (eq (char-before) ?:)) | ||
| 488 | (not (c-in-literal)) | ||
| 489 | (not (eq (char-after (- (point) 2)) ?:))) | ||
| 490 | (delete-region (point) (1- here))) | ||
| 491 | (goto-char (- (point-max) pos))) | ||
| 492 | ;; lets do some special stuff with the colon character | ||
| 493 | (setq syntax (c-guess-basic-syntax) | ||
| 494 | ;; some language elements can only be determined by | ||
| 495 | ;; checking the following line. Lets first look for ones | ||
| 496 | ;; that can be found when looking on the line with the | ||
| 497 | ;; colon | ||
| 498 | newlines | ||
| 499 | (and c-auto-newline | ||
| 500 | (or (c-lookup-lists '(case-label label access-label) | ||
| 501 | syntax c-hanging-colons-alist) | ||
| 502 | (c-lookup-lists '(member-init-intro inher-intro) | ||
| 503 | (prog2 | ||
| 504 | (insert "\n") | ||
| 505 | (c-guess-basic-syntax) | ||
| 506 | (delete-char -1)) | ||
| 507 | c-hanging-colons-alist)))) | ||
| 508 | ;; indent the current line | ||
| 509 | (c-indent-line syntax) | ||
| 510 | ;; does a newline go before the colon? Watch out for already | ||
| 511 | ;; non-hung colons. However, we don't unhang them because that | ||
| 512 | ;; would be a cleanup (and anti-social). | ||
| 513 | (if (and (memq 'before newlines) | ||
| 514 | (save-excursion | ||
| 515 | (skip-chars-backward ": \t") | ||
| 516 | (not (bolp)))) | ||
| 517 | (let ((pos (- (point-max) (point)))) | ||
| 518 | (forward-char -1) | ||
| 519 | (newline) | ||
| 520 | (c-indent-line) | ||
| 521 | (goto-char (- (point-max) pos)))) | ||
| 522 | ;; does a newline go after the colon? | ||
| 523 | (if (memq 'after (cdr-safe newlines)) | ||
| 524 | (progn | ||
| 525 | (newline) | ||
| 526 | (c-indent-line))) | ||
| 527 | ))) | ||
| 528 | |||
| 529 | (defun c-electric-lt-gt (arg) | ||
| 530 | "Insert a less-than, or greater-than character. | ||
| 531 | When the auto-newline feature is turned on, as evidenced by the \"/a\" | ||
| 532 | or \"/ah\" string on the mode line, the line will be re-indented if | ||
| 533 | the character inserted is the second of a C++ style stream operator | ||
| 534 | and the buffer is in C++ mode. | ||
| 535 | |||
| 536 | The line will also not be re-indented if a numeric argument is | ||
| 537 | supplied, or point is inside a literal." | ||
| 538 | (interactive "P") | ||
| 539 | (let ((indentp (and (not arg) | ||
| 540 | (eq (char-before) last-command-char) | ||
| 541 | (not (c-in-literal)))) | ||
| 542 | ;; shut this up | ||
| 543 | (c-echo-syntactic-information-p nil)) | ||
| 544 | (self-insert-command (prefix-numeric-value arg)) | ||
| 545 | (if indentp | ||
| 546 | (c-indent-line)))) | ||
| 547 | |||
| 548 | |||
| 549 | |||
| 550 | ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus | ||
| 551 | ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com | ||
| 552 | (defun c-forward-into-nomenclature (&optional arg) | ||
| 553 | "Move forward to end of a nomenclature section or word. | ||
| 554 | With arg, to it arg times." | ||
| 555 | (interactive "p") | ||
| 556 | (let ((case-fold-search nil)) | ||
| 557 | (if (> arg 0) | ||
| 558 | (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg) | ||
| 559 | (while (and (< arg 0) | ||
| 560 | (re-search-backward | ||
| 561 | "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)" | ||
| 562 | (point-min) 0)) | ||
| 563 | (forward-char 1) | ||
| 564 | (setq arg (1+ arg))))) | ||
| 565 | (c-keep-region-active)) | ||
| 566 | |||
| 567 | (defun c-backward-into-nomenclature (&optional arg) | ||
| 568 | "Move backward to beginning of a nomenclature section or word. | ||
| 569 | With optional ARG, move that many times. If ARG is negative, move | ||
| 570 | forward." | ||
| 571 | (interactive "p") | ||
| 572 | (c-forward-into-nomenclature (- arg)) | ||
| 573 | (c-keep-region-active)) | ||
| 574 | |||
| 575 | (defun c-scope-operator () | ||
| 576 | "Insert a double colon scope operator at point. | ||
| 577 | No indentation or other \"electric\" behavior is performed." | ||
| 578 | (interactive) | ||
| 579 | (insert "::")) | ||
| 580 | |||
| 581 | |||
| 582 | (defun c-beginning-of-statement (&optional count lim sentence-flag) | ||
| 583 | "Go to the beginning of the innermost C statement. | ||
| 584 | With prefix arg, go back N - 1 statements. If already at the | ||
| 585 | beginning of a statement then go to the beginning of the preceding | ||
| 586 | one. If within a string or comment, or next to a comment (only | ||
| 587 | whitespace between), move by sentences instead of statements. | ||
| 588 | |||
| 589 | When called from a program, this function takes 3 optional args: the | ||
| 590 | repetition count, a buffer position limit which is the farthest back | ||
| 591 | to search, and a flag saying whether to do sentence motion when in a | ||
| 592 | comment." | ||
| 593 | (interactive (list (prefix-numeric-value current-prefix-arg) | ||
| 594 | nil t)) | ||
| 595 | (let ((here (point)) | ||
| 596 | (count (or count 1)) | ||
| 597 | (lim (or lim (c-point 'bod))) | ||
| 598 | state) | ||
| 599 | (save-excursion | ||
| 600 | (goto-char lim) | ||
| 601 | (setq state (parse-partial-sexp (point) here nil nil))) | ||
| 602 | (if (and sentence-flag | ||
| 603 | (or (nth 3 state) | ||
| 604 | (nth 4 state) | ||
| 605 | ; (looking-at (concat "[ \t]*" comment-start-skip)) | ||
| 606 | (save-excursion | ||
| 607 | (skip-chars-backward " \t") | ||
| 608 | (goto-char (- (point) 2)) | ||
| 609 | (looking-at "\\*/")))) | ||
| 610 | (forward-sentence (- count)) | ||
| 611 | (while (> count 0) | ||
| 612 | (c-beginning-of-statement-1 lim) | ||
| 613 | (setq count (1- count))) | ||
| 614 | (while (< count 0) | ||
| 615 | (c-end-of-statement-1) | ||
| 616 | (setq count (1+ count)))) | ||
| 617 | ;; its possible we've been left up-buf of lim | ||
| 618 | (goto-char (max (point) lim)) | ||
| 619 | ) | ||
| 620 | (c-keep-region-active)) | ||
| 621 | |||
| 622 | (defun c-end-of-statement (&optional count lim sentence-flag) | ||
| 623 | "Go to the end of the innermost C statement. | ||
| 624 | |||
| 625 | With prefix arg, go forward N - 1 statements. Move forward to end of | ||
| 626 | the next statement if already at end. If within a string or comment, | ||
| 627 | move by sentences instead of statements. | ||
| 628 | |||
| 629 | When called from a program, this function takes 3 optional args: the | ||
| 630 | repetition count, a buffer position limit which is the farthest back | ||
| 631 | to search, and a flag saying whether to do sentence motion when in a | ||
| 632 | comment." | ||
| 633 | (interactive (list (prefix-numeric-value current-prefix-arg) | ||
| 634 | nil t)) | ||
| 635 | (c-beginning-of-statement (- (or count 1)) lim sentence-flag) | ||
| 636 | (c-keep-region-active)) | ||
| 637 | |||
| 638 | |||
| 639 | ;; set up electric character functions to work with pending-del, | ||
| 640 | ;; (a.k.a. delsel) mode. All symbols get the t value except | ||
| 641 | ;; c-electric-delete which gets 'supersede. | ||
| 642 | (mapcar | ||
| 643 | (function | ||
| 644 | (lambda (sym) | ||
| 645 | (put sym 'delete-selection t) ; for delsel (Emacs) | ||
| 646 | (put sym 'pending-delete t))) ; for pending-del (XEmacs) | ||
| 647 | '(c-electric-pound | ||
| 648 | c-electric-brace | ||
| 649 | c-electric-slash | ||
| 650 | c-electric-star | ||
| 651 | c-electric-semi&comma | ||
| 652 | c-electric-lt-gt | ||
| 653 | c-electric-colon)) | ||
| 654 | (put 'c-electric-delete 'delete-selection 'supersede) ; delsel | ||
| 655 | (put 'c-electric-delete 'pending-delete 'supersede) ; pending-del | ||
| 656 | |||
| 657 | |||
| 658 | ;; This is used by indent-for-comment to decide how much to indent a | ||
| 659 | ;; comment in C code based on its context. | ||
| 660 | (defun c-comment-indent () | ||
| 661 | (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)")) | ||
| 662 | 0 ;Existing comment at bol stays there. | ||
| 663 | (let ((opoint (point)) | ||
| 664 | placeholder) | ||
| 665 | (save-excursion | ||
| 666 | (beginning-of-line) | ||
| 667 | (cond | ||
| 668 | ;; CASE 1: A comment following a solitary close-brace should | ||
| 669 | ;; have only one space. | ||
| 670 | ((looking-at (concat "[ \t]*}[ \t]*\\($\\|" | ||
| 671 | c-comment-start-regexp | ||
| 672 | "\\)")) | ||
| 673 | (search-forward "}") | ||
| 674 | (1+ (current-column))) | ||
| 675 | ;; CASE 2: 2 spaces after #endif | ||
| 676 | ((or (looking-at "^#[ \t]*endif[ \t]*") | ||
| 677 | (looking-at "^#[ \t]*else[ \t]*")) | ||
| 678 | 7) | ||
| 679 | ;; CASE 3: when comment-column is nil, calculate the offset | ||
| 680 | ;; according to c-offsets-alist. E.g. identical to hitting | ||
| 681 | ;; TAB. | ||
| 682 | ((and c-indent-comments-syntactically-p | ||
| 683 | (save-excursion | ||
| 684 | (skip-chars-forward " \t") | ||
| 685 | (or (looking-at comment-start) | ||
| 686 | (eolp)))) | ||
| 687 | (let ((syntax (c-guess-basic-syntax))) | ||
| 688 | ;; BOGOSITY ALERT: if we're looking at the eol, its | ||
| 689 | ;; because indent-for-comment hasn't put the comment-start | ||
| 690 | ;; in the buffer yet. this will screw up the syntactic | ||
| 691 | ;; analysis so we kludge in the necessary info. Another | ||
| 692 | ;; kludge is that if we're at the bol, then we really want | ||
| 693 | ;; to ignore any anchoring as specified by | ||
| 694 | ;; c-comment-only-line-offset since it doesn't apply here. | ||
| 695 | (if (save-excursion | ||
| 696 | (beginning-of-line) | ||
| 697 | (skip-chars-forward " \t") | ||
| 698 | (eolp)) | ||
| 699 | (c-add-syntax 'comment-intro)) | ||
| 700 | (let ((c-comment-only-line-offset | ||
| 701 | (if (consp c-comment-only-line-offset) | ||
| 702 | c-comment-only-line-offset | ||
| 703 | (cons c-comment-only-line-offset | ||
| 704 | c-comment-only-line-offset)))) | ||
| 705 | (apply '+ (mapcar 'c-get-offset syntax))))) | ||
| 706 | ;; CASE 4: use comment-column if previous line is a | ||
| 707 | ;; comment-only line indented to the left of comment-column | ||
| 708 | ((save-excursion | ||
| 709 | (beginning-of-line) | ||
| 710 | (and (not (bobp)) | ||
| 711 | (forward-line -1)) | ||
| 712 | (skip-chars-forward " \t") | ||
| 713 | (prog1 | ||
| 714 | (looking-at c-comment-start-regexp) | ||
| 715 | (setq placeholder (point)))) | ||
| 716 | (goto-char placeholder) | ||
| 717 | (if (< (current-column) comment-column) | ||
| 718 | comment-column | ||
| 719 | (current-column))) | ||
| 720 | ;; CASE 5: If comment-column is 0, and nothing but space | ||
| 721 | ;; before the comment, align it at 0 rather than 1. | ||
| 722 | ((progn | ||
| 723 | (goto-char opoint) | ||
| 724 | (skip-chars-backward " \t") | ||
| 725 | (and (= comment-column 0) (bolp))) | ||
| 726 | 0) | ||
| 727 | ;; CASE 6: indent at comment column except leave at least one | ||
| 728 | ;; space. | ||
| 729 | (t (max (1+ (current-column)) | ||
| 730 | comment-column)) | ||
| 731 | ))))) | ||
| 732 | |||
| 733 | ;; used by outline-minor-mode | ||
| 734 | (defun c-outline-level () | ||
| 735 | (save-excursion | ||
| 736 | (skip-chars-forward "\t ") | ||
| 737 | (current-column))) | ||
| 738 | |||
| 739 | |||
| 740 | (defun c-up-conditional (count) | ||
| 741 | "Move back to the containing preprocessor conditional, leaving mark behind. | ||
| 742 | A prefix argument acts as a repeat count. With a negative argument, | ||
| 743 | move forward to the end of the containing preprocessor conditional. | ||
| 744 | When going backwards, `#elif' is treated like `#else' followed by | ||
| 745 | `#if'. When going forwards, `#elif' is ignored." | ||
| 746 | (interactive "p") | ||
| 747 | (c-forward-conditional (- count) t) | ||
| 748 | (c-keep-region-active)) | ||
| 749 | |||
| 750 | (defun c-backward-conditional (count &optional up-flag) | ||
| 751 | "Move back across a preprocessor conditional, leaving mark behind. | ||
| 752 | A prefix argument acts as a repeat count. With a negative argument, | ||
| 753 | move forward across a preprocessor conditional." | ||
| 754 | (interactive "p") | ||
| 755 | (c-forward-conditional (- count) up-flag) | ||
| 756 | (c-keep-region-active)) | ||
| 757 | |||
| 758 | (defun c-forward-conditional (count &optional up-flag) | ||
| 759 | "Move forward across a preprocessor conditional, leaving mark behind. | ||
| 760 | A prefix argument acts as a repeat count. With a negative argument, | ||
| 761 | move backward across a preprocessor conditional." | ||
| 762 | (interactive "p") | ||
| 763 | (let* ((forward (> count 0)) | ||
| 764 | (increment (if forward -1 1)) | ||
| 765 | (search-function (if forward 're-search-forward 're-search-backward)) | ||
| 766 | (new)) | ||
| 767 | (save-excursion | ||
| 768 | (while (/= count 0) | ||
| 769 | (let ((depth (if up-flag 0 -1)) found) | ||
| 770 | (save-excursion | ||
| 771 | ;; Find the "next" significant line in the proper direction. | ||
| 772 | (while (and (not found) | ||
| 773 | ;; Rather than searching for a # sign that | ||
| 774 | ;; comes at the beginning of a line aside from | ||
| 775 | ;; whitespace, search first for a string | ||
| 776 | ;; starting with # sign. Then verify what | ||
| 777 | ;; precedes it. This is faster on account of | ||
| 778 | ;; the fastmap feature of the regexp matcher. | ||
| 779 | (funcall search-function | ||
| 780 | "#[ \t]*\\(if\\|elif\\|endif\\)" | ||
| 781 | nil t)) | ||
| 782 | (beginning-of-line) | ||
| 783 | ;; Now verify it is really a preproc line. | ||
| 784 | (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)") | ||
| 785 | (let ((prev depth)) | ||
| 786 | ;; Update depth according to what we found. | ||
| 787 | (beginning-of-line) | ||
| 788 | (cond ((looking-at "[ \t]*#[ \t]*endif") | ||
| 789 | (setq depth (+ depth increment))) | ||
| 790 | ((looking-at "[ \t]*#[ \t]*elif") | ||
| 791 | (if (and forward (= depth 0)) | ||
| 792 | (setq found (point)))) | ||
| 793 | (t (setq depth (- depth increment)))) | ||
| 794 | ;; If we are trying to move across, and we find an | ||
| 795 | ;; end before we find a beginning, get an error. | ||
| 796 | (if (and (< prev 0) (< depth prev)) | ||
| 797 | (error (if forward | ||
| 798 | "No following conditional at this level" | ||
| 799 | "No previous conditional at this level"))) | ||
| 800 | ;; When searching forward, start from next line so | ||
| 801 | ;; that we don't find the same line again. | ||
| 802 | (if forward (forward-line 1)) | ||
| 803 | ;; If this line exits a level of conditional, exit | ||
| 804 | ;; inner loop. | ||
| 805 | (if (< depth 0) | ||
| 806 | (setq found (point)))) | ||
| 807 | ;; else | ||
| 808 | (if forward (forward-line 1)) | ||
| 809 | ))) | ||
| 810 | (or found | ||
| 811 | (error "No containing preprocessor conditional")) | ||
| 812 | (goto-char (setq new found))) | ||
| 813 | (setq count (+ count increment)))) | ||
| 814 | (push-mark) | ||
| 815 | (goto-char new)) | ||
| 816 | (c-keep-region-active)) | ||
| 817 | |||
| 818 | |||
| 819 | ;; commands to indent lines, regions, defuns, and expressions | ||
| 820 | (defun c-indent-command (&optional whole-exp) | ||
| 821 | "Indent current line as C code, and/or insert some whitespace. | ||
| 822 | |||
| 823 | If `c-tab-always-indent' is t, always just indent the current line. | ||
| 824 | If nil, indent the current line only if point is at the left margin or | ||
| 825 | in the line's indentation; otherwise insert some whitespace[*]. If | ||
| 826 | other than nil or t, then some whitespace[*] is inserted only within | ||
| 827 | literals (comments and strings) and inside preprocessor directives, | ||
| 828 | but the line is always reindented. | ||
| 829 | |||
| 830 | A numeric argument, regardless of its value, means indent rigidly all | ||
| 831 | the lines of the expression starting after point so that this line | ||
| 832 | becomes properly indented. The relative indentation among the lines | ||
| 833 | of the expression are preserved. | ||
| 834 | |||
| 835 | [*] The amount and kind of whitespace inserted is controlled by the | ||
| 836 | variable `c-insert-tab-function', which is called to do the actual | ||
| 837 | insertion of whitespace. Normally the function in this variable | ||
| 838 | just inserts a tab character, or the equivalent number of spaces, | ||
| 839 | depending on the variable `indent-tabs-mode'." | ||
| 840 | |||
| 841 | (interactive "P") | ||
| 842 | (let ((bod (c-point 'bod))) | ||
| 843 | (if whole-exp | ||
| 844 | ;; If arg, always indent this line as C | ||
| 845 | ;; and shift remaining lines of expression the same amount. | ||
| 846 | (let ((shift-amt (c-indent-line)) | ||
| 847 | beg end) | ||
| 848 | (save-excursion | ||
| 849 | (if (eq c-tab-always-indent t) | ||
| 850 | (beginning-of-line)) | ||
| 851 | (setq beg (point)) | ||
| 852 | (forward-sexp 1) | ||
| 853 | (setq end (point)) | ||
| 854 | (goto-char beg) | ||
| 855 | (forward-line 1) | ||
| 856 | (setq beg (point))) | ||
| 857 | (if (> end beg) | ||
| 858 | (indent-code-rigidly beg end (- shift-amt) "#"))) | ||
| 859 | ;; No arg supplied, use c-tab-always-indent to determine | ||
| 860 | ;; behavior | ||
| 861 | (cond | ||
| 862 | ;; CASE 1: indent when at column zero or in lines indentation, | ||
| 863 | ;; otherwise insert a tab | ||
| 864 | ((not c-tab-always-indent) | ||
| 865 | (if (save-excursion | ||
| 866 | (skip-chars-backward " \t") | ||
| 867 | (not (bolp))) | ||
| 868 | (funcall c-insert-tab-function) | ||
| 869 | (c-indent-line))) | ||
| 870 | ;; CASE 2: just indent the line | ||
| 871 | ((eq c-tab-always-indent t) | ||
| 872 | (c-indent-line)) | ||
| 873 | ;; CASE 3: if in a literal, insert a tab, but always indent the | ||
| 874 | ;; line | ||
| 875 | (t | ||
| 876 | (if (c-in-literal bod) | ||
| 877 | (funcall c-insert-tab-function)) | ||
| 878 | (c-indent-line) | ||
| 879 | ))))) | ||
| 880 | |||
| 881 | (defun c-indent-exp (&optional shutup-p) | ||
| 882 | "Indent each line in balanced expression following point. | ||
| 883 | Optional SHUTUP-P if non-nil, inhibits message printing and error checking." | ||
| 884 | (interactive "P") | ||
| 885 | (let ((here (point)) | ||
| 886 | end progress-p) | ||
| 887 | (unwind-protect | ||
| 888 | (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed | ||
| 889 | (start (progn | ||
| 890 | ;; try to be smarter about finding the range of | ||
| 891 | ;; lines to indent. skip all following | ||
| 892 | ;; whitespace. failing that, try to find any | ||
| 893 | ;; opening brace on the current line | ||
| 894 | (skip-chars-forward " \t\n") | ||
| 895 | (if (memq (char-after) '(?\( ?\[ ?\{)) | ||
| 896 | (point) | ||
| 897 | (let ((state (parse-partial-sexp (point) | ||
| 898 | (c-point 'eol)))) | ||
| 899 | (and (nth 1 state) | ||
| 900 | (goto-char (nth 1 state)) | ||
| 901 | (memq (char-after) '(?\( ?\[ ?\{)) | ||
| 902 | (point))))))) | ||
| 903 | ;; find balanced expression end | ||
| 904 | (setq end (and (c-safe (progn (forward-sexp 1) t)) | ||
| 905 | (point-marker))) | ||
| 906 | ;; sanity check | ||
| 907 | (and (not start) | ||
| 908 | (not shutup-p) | ||
| 909 | (error "Cannot find start of balanced expression to indent.")) | ||
| 910 | (and (not end) | ||
| 911 | (not shutup-p) | ||
| 912 | (error "Cannot find end of balanced expression to indent.")) | ||
| 913 | (c-progress-init start end 'c-indent-exp) | ||
| 914 | (setq progress-p t) | ||
| 915 | (goto-char start) | ||
| 916 | (beginning-of-line) | ||
| 917 | (while (< (point) end) | ||
| 918 | (if (not (looking-at "[ \t]*$")) | ||
| 919 | (c-indent-line)) | ||
| 920 | (c-progress-update) | ||
| 921 | (forward-line 1))) | ||
| 922 | ;; make sure marker is deleted | ||
| 923 | (and end | ||
| 924 | (set-marker end nil)) | ||
| 925 | (and progress-p | ||
| 926 | (c-progress-fini 'c-indent-exp)) | ||
| 927 | (goto-char here)))) | ||
| 928 | |||
| 929 | (defun c-indent-defun () | ||
| 930 | "Re-indents the current top-level function def, struct or class declaration." | ||
| 931 | (interactive) | ||
| 932 | (let ((here (point-marker)) | ||
| 933 | (c-echo-syntactic-information-p nil) | ||
| 934 | (brace (c-least-enclosing-brace (c-parse-state)))) | ||
| 935 | (if brace | ||
| 936 | (goto-char brace) | ||
| 937 | (beginning-of-defun)) | ||
| 938 | ;; if we're sitting at b-o-b, it might be because there was no | ||
| 939 | ;; least enclosing brace and we were sitting on the defun's open | ||
| 940 | ;; brace. | ||
| 941 | (if (and (bobp) (not (eq (char-after) ?\{))) | ||
| 942 | (goto-char here)) | ||
| 943 | ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at | ||
| 944 | ;; the open brace. I consider this an Emacs bug. | ||
| 945 | (and (boundp 'defun-prompt-regexp) | ||
| 946 | defun-prompt-regexp | ||
| 947 | (looking-at defun-prompt-regexp) | ||
| 948 | (goto-char (match-end 0))) | ||
| 949 | ;; catch all errors in c-indent-exp so we can 1. give more | ||
| 950 | ;; meaningful error message, and 2. restore point | ||
| 951 | (unwind-protect | ||
| 952 | (c-indent-exp) | ||
| 953 | (goto-char here) | ||
| 954 | (set-marker here nil)))) | ||
| 955 | |||
| 956 | (defun c-indent-region (start end) | ||
| 957 | ;; Indent every line whose first char is between START and END inclusive. | ||
| 958 | (save-excursion | ||
| 959 | (goto-char start) | ||
| 960 | ;; Advance to first nonblank line. | ||
| 961 | (skip-chars-forward " \t\n") | ||
| 962 | (beginning-of-line) | ||
| 963 | (let (endmark) | ||
| 964 | (unwind-protect | ||
| 965 | (let ((c-tab-always-indent t) | ||
| 966 | ;; shut up any echo msgs on indiv lines | ||
| 967 | (c-echo-syntactic-information-p nil) | ||
| 968 | fence) | ||
| 969 | (c-progress-init start end 'c-indent-region) | ||
| 970 | (setq endmark (copy-marker end)) | ||
| 971 | (while (and (bolp) | ||
| 972 | (not (eobp)) | ||
| 973 | (< (point) endmark)) | ||
| 974 | ;; update progress | ||
| 975 | (c-progress-update) | ||
| 976 | ;; Indent one line as with TAB. | ||
| 977 | (let (nextline sexpend sexpbeg) | ||
| 978 | ;; skip blank lines | ||
| 979 | (skip-chars-forward " \t\n") | ||
| 980 | (beginning-of-line) | ||
| 981 | ;; indent the current line | ||
| 982 | (c-indent-line) | ||
| 983 | (setq fence (point)) | ||
| 984 | (if (save-excursion | ||
| 985 | (beginning-of-line) | ||
| 986 | (looking-at "[ \t]*#")) | ||
| 987 | (forward-line 1) | ||
| 988 | (save-excursion | ||
| 989 | ;; Find beginning of following line. | ||
| 990 | (setq nextline (c-point 'bonl)) | ||
| 991 | ;; Find first beginning-of-sexp for sexp extending past | ||
| 992 | ;; this line. | ||
| 993 | (beginning-of-line) | ||
| 994 | (while (< (point) nextline) | ||
| 995 | (condition-case nil | ||
| 996 | (progn | ||
| 997 | (forward-sexp 1) | ||
| 998 | (setq sexpend (point))) | ||
| 999 | (error (setq sexpend nil) | ||
| 1000 | (goto-char nextline))) | ||
| 1001 | (c-forward-syntactic-ws)) | ||
| 1002 | (if sexpend | ||
| 1003 | (progn | ||
| 1004 | ;; make sure the sexp we found really starts on the | ||
| 1005 | ;; current line and extends past it | ||
| 1006 | (goto-char sexpend) | ||
| 1007 | (setq sexpend (point-marker)) | ||
| 1008 | (c-safe (backward-sexp 1)) | ||
| 1009 | (setq sexpbeg (point)))) | ||
| 1010 | (if (and sexpbeg (< sexpbeg fence)) | ||
| 1011 | (setq sexpbeg fence))) | ||
| 1012 | ;; check to see if the next line starts a | ||
| 1013 | ;; comment-only line | ||
| 1014 | (save-excursion | ||
| 1015 | (forward-line 1) | ||
| 1016 | (skip-chars-forward " \t") | ||
| 1017 | (if (looking-at c-comment-start-regexp) | ||
| 1018 | (setq sexpbeg (c-point 'bol)))) | ||
| 1019 | ;; If that sexp ends within the region, indent it all at | ||
| 1020 | ;; once, fast. | ||
| 1021 | (condition-case nil | ||
| 1022 | (if (and sexpend | ||
| 1023 | (> sexpend nextline) | ||
| 1024 | (<= sexpend endmark)) | ||
| 1025 | (progn | ||
| 1026 | (goto-char sexpbeg) | ||
| 1027 | (c-indent-exp 'shutup) | ||
| 1028 | (c-progress-update) | ||
| 1029 | (goto-char sexpend))) | ||
| 1030 | (error | ||
| 1031 | (goto-char sexpbeg) | ||
| 1032 | (c-indent-line))) | ||
| 1033 | ;; Move to following line and try again. | ||
| 1034 | (and sexpend | ||
| 1035 | (markerp sexpend) | ||
| 1036 | (set-marker sexpend nil)) | ||
| 1037 | (forward-line 1) | ||
| 1038 | (setq fence (point)))))) | ||
| 1039 | (set-marker endmark nil) | ||
| 1040 | (c-progress-fini 'c-indent-region) | ||
| 1041 | (c-echo-parsing-error) | ||
| 1042 | )))) | ||
| 1043 | |||
| 1044 | (defun c-mark-function () | ||
| 1045 | "Put mark at end of a C, C++, or Objective-C defun, point at beginning." | ||
| 1046 | (interactive) | ||
| 1047 | (let ((here (point)) | ||
| 1048 | ;; there should be a c-point position for 'eod | ||
| 1049 | (eod (save-excursion (end-of-defun) (point))) | ||
| 1050 | (state (c-parse-state)) | ||
| 1051 | brace) | ||
| 1052 | (while state | ||
| 1053 | (setq brace (car state)) | ||
| 1054 | (if (consp brace) | ||
| 1055 | (goto-char (cdr brace)) | ||
| 1056 | (goto-char brace)) | ||
| 1057 | (setq state (cdr state))) | ||
| 1058 | (if (eq (char-after) ?{) | ||
| 1059 | (progn | ||
| 1060 | (forward-line -1) | ||
| 1061 | (while (not (or (bobp) | ||
| 1062 | (looking-at "[ \t]*$"))) | ||
| 1063 | (forward-line -1))) | ||
| 1064 | (forward-line 1) | ||
| 1065 | (skip-chars-forward " \t\n")) | ||
| 1066 | (push-mark here) | ||
| 1067 | (push-mark eod nil t))) | ||
| 1068 | |||
| 1069 | |||
| 1070 | ;; for progress reporting | ||
| 1071 | (defvar c-progress-info nil) | ||
| 1072 | |||
| 1073 | (defun c-progress-init (start end context) | ||
| 1074 | ;; start the progress update messages. if this emacs doesn't have a | ||
| 1075 | ;; built-in timer, just be dumb about it | ||
| 1076 | (if (not (fboundp 'current-time)) | ||
| 1077 | (message "indenting region... (this may take a while)") | ||
| 1078 | ;; if progress has already been initialized, do nothing. otherwise | ||
| 1079 | ;; initialize the counter with a vector of: | ||
| 1080 | ;; [start end lastsec context] | ||
| 1081 | (if c-progress-info | ||
| 1082 | () | ||
| 1083 | (setq c-progress-info (vector start | ||
| 1084 | (save-excursion | ||
| 1085 | (goto-char end) | ||
| 1086 | (point-marker)) | ||
| 1087 | (nth 1 (current-time)) | ||
| 1088 | context)) | ||
| 1089 | (message "indenting region...")))) | ||
| 1090 | |||
| 1091 | (defun c-progress-update () | ||
| 1092 | ;; update progress | ||
| 1093 | (if (not (and c-progress-info c-progress-interval)) | ||
| 1094 | nil | ||
| 1095 | (let ((now (nth 1 (current-time))) | ||
| 1096 | (start (aref c-progress-info 0)) | ||
| 1097 | (end (aref c-progress-info 1)) | ||
| 1098 | (lastsecs (aref c-progress-info 2))) | ||
| 1099 | ;; should we update? currently, update happens every 2 seconds, | ||
| 1100 | ;; what's the right value? | ||
| 1101 | (if (< c-progress-interval (- now lastsecs)) | ||
| 1102 | (progn | ||
| 1103 | (message "indenting region... (%d%% complete)" | ||
| 1104 | (/ (* 100 (- (point) start)) (- end start))) | ||
| 1105 | (aset c-progress-info 2 now))) | ||
| 1106 | ))) | ||
| 1107 | |||
| 1108 | (defun c-progress-fini (context) | ||
| 1109 | ;; finished | ||
| 1110 | (if (or (eq context (aref c-progress-info 3)) | ||
| 1111 | (eq context t)) | ||
| 1112 | (progn | ||
| 1113 | (set-marker (aref c-progress-info 1) nil) | ||
| 1114 | (setq c-progress-info nil) | ||
| 1115 | (message "indenting region...done")))) | ||
| 1116 | |||
| 1117 | |||
| 1118 | |||
| 1119 | ;;; This page handles insertion and removal of backslashes for C macros. | ||
| 1120 | |||
| 1121 | (defun c-backslash-region (from to delete-flag) | ||
| 1122 | "Insert, align, or delete end-of-line backslashes on the lines in the region. | ||
| 1123 | With no argument, inserts backslashes and aligns existing backslashes. | ||
| 1124 | With an argument, deletes the backslashes. | ||
| 1125 | |||
| 1126 | This function does not modify blank lines at the start of the region. | ||
| 1127 | If the region ends at the start of a line, it always deletes the | ||
| 1128 | backslash (if any) at the end of the previous line. | ||
| 1129 | |||
| 1130 | You can put the region around an entire macro definition and use this | ||
| 1131 | command to conveniently insert and align the necessary backslashes." | ||
| 1132 | (interactive "r\nP") | ||
| 1133 | (save-excursion | ||
| 1134 | (goto-char from) | ||
| 1135 | (let ((column c-backslash-column) | ||
| 1136 | (endmark (make-marker))) | ||
| 1137 | (move-marker endmark to) | ||
| 1138 | ;; Compute the smallest column number past the ends of all the lines. | ||
| 1139 | (if (not delete-flag) | ||
| 1140 | (while (< (point) to) | ||
| 1141 | (end-of-line) | ||
| 1142 | (if (eq (char-before) ?\\) | ||
| 1143 | (progn (forward-char -1) | ||
| 1144 | (skip-chars-backward " \t"))) | ||
| 1145 | (setq column (max column (1+ (current-column)))) | ||
| 1146 | (forward-line 1))) | ||
| 1147 | ;; Adjust upward to a tab column, if that doesn't push past the margin. | ||
| 1148 | (if (> (% column tab-width) 0) | ||
| 1149 | (let ((adjusted (* (/ (+ column tab-width -1) tab-width) tab-width))) | ||
| 1150 | (if (< adjusted (window-width)) | ||
| 1151 | (setq column adjusted)))) | ||
| 1152 | ;; Don't modify blank lines at start of region. | ||
| 1153 | (goto-char from) | ||
| 1154 | (while (and (< (point) endmark) (eolp)) | ||
| 1155 | (forward-line 1)) | ||
| 1156 | ;; Add or remove backslashes on all the lines. | ||
| 1157 | (while (< (point) endmark) | ||
| 1158 | (if (and (not delete-flag) | ||
| 1159 | ;; Un-backslashify the last line | ||
| 1160 | ;; if the region ends right at the start of the next line. | ||
| 1161 | (save-excursion | ||
| 1162 | (forward-line 1) | ||
| 1163 | (< (point) endmark))) | ||
| 1164 | (c-append-backslash column) | ||
| 1165 | (c-delete-backslash)) | ||
| 1166 | (forward-line 1)) | ||
| 1167 | (move-marker endmark nil))) | ||
| 1168 | (c-keep-region-active)) | ||
| 1169 | |||
| 1170 | (defun c-append-backslash (column) | ||
| 1171 | (end-of-line) | ||
| 1172 | (if (eq (char-before) ?\\) | ||
| 1173 | (progn (forward-char -1) | ||
| 1174 | (delete-horizontal-space) | ||
| 1175 | (indent-to column)) | ||
| 1176 | (indent-to column) | ||
| 1177 | (insert "\\"))) | ||
| 1178 | |||
| 1179 | (defun c-delete-backslash () | ||
| 1180 | (end-of-line) | ||
| 1181 | (or (bolp) | ||
| 1182 | (progn | ||
| 1183 | (forward-char -1) | ||
| 1184 | (if (looking-at "\\\\") | ||
| 1185 | (delete-region (1+ (point)) | ||
| 1186 | (progn (skip-chars-backward " \t") (point))))))) | ||
| 1187 | |||
| 1188 | |||
| 1189 | (defun c-fill-paragraph (&optional arg) | ||
| 1190 | "Like \\[fill-paragraph] but handles C and C++ style comments. | ||
| 1191 | If any of the current line is a comment or within a comment, | ||
| 1192 | fill the comment or the paragraph of it that point is in, | ||
| 1193 | preserving the comment indentation or line-starting decorations. | ||
| 1194 | |||
| 1195 | Optional prefix ARG means justify paragraph as well." | ||
| 1196 | (interactive "P") | ||
| 1197 | (let* (comment-start-place | ||
| 1198 | (first-line | ||
| 1199 | ;; Check for obvious entry to comment. | ||
| 1200 | (save-excursion | ||
| 1201 | (beginning-of-line) | ||
| 1202 | (skip-chars-forward " \t\n") | ||
| 1203 | (and (looking-at comment-start-skip) | ||
| 1204 | (setq comment-start-place (point))))) | ||
| 1205 | (re1 "\\|[ \t]*/\\*[ \t]*$\\|[ \t]*\\*/[ \t]*$\\|[ \t/*]*$")) | ||
| 1206 | (if (and c-double-slash-is-comments-p | ||
| 1207 | (save-excursion | ||
| 1208 | (beginning-of-line) | ||
| 1209 | (looking-at ".*//"))) | ||
| 1210 | (let ((fill-prefix fill-prefix) | ||
| 1211 | ;; Lines containing just a comment start or just an end | ||
| 1212 | ;; should not be filled into paragraphs they are next | ||
| 1213 | ;; to. | ||
| 1214 | (paragraph-start (concat paragraph-start re1)) | ||
| 1215 | (paragraph-separate (concat paragraph-separate re1))) | ||
| 1216 | (save-excursion | ||
| 1217 | (beginning-of-line) | ||
| 1218 | ;; Move up to first line of this comment. | ||
| 1219 | (while (and (not (bobp)) | ||
| 1220 | (looking-at "[ \t]*//[ \t]*[^ \t\n]")) | ||
| 1221 | (forward-line -1)) | ||
| 1222 | (if (not (looking-at ".*//[ \t]*[^ \t\n]")) | ||
| 1223 | (forward-line 1)) | ||
| 1224 | ;; Find the comment start in this line. | ||
| 1225 | (re-search-forward "[ \t]*//[ \t]*") | ||
| 1226 | ;; Set the fill-prefix to be what all lines except the first | ||
| 1227 | ;; should start with. But do not alter a user set fill-prefix. | ||
| 1228 | (if (null fill-prefix) | ||
| 1229 | (setq fill-prefix (buffer-substring (match-beginning 0) | ||
| 1230 | (match-end 0)))) | ||
| 1231 | (save-restriction | ||
| 1232 | ;; Narrow down to just the lines of this comment. | ||
| 1233 | (narrow-to-region (c-point 'bol) | ||
| 1234 | (save-excursion | ||
| 1235 | (forward-line 1) | ||
| 1236 | (while (looking-at fill-prefix) | ||
| 1237 | (forward-line 1)) | ||
| 1238 | (point))) | ||
| 1239 | (fill-paragraph arg) | ||
| 1240 | t))) | ||
| 1241 | ;; else C style comments | ||
| 1242 | (if (or first-line | ||
| 1243 | ;; t if we enter a comment between start of function and | ||
| 1244 | ;; this line. | ||
| 1245 | (eq (c-in-literal) 'c) | ||
| 1246 | ;; t if this line contains a comment starter. | ||
| 1247 | (setq first-line | ||
| 1248 | (save-excursion | ||
| 1249 | (beginning-of-line) | ||
| 1250 | (prog1 | ||
| 1251 | (re-search-forward comment-start-skip | ||
| 1252 | (save-excursion (end-of-line) | ||
| 1253 | (point)) | ||
| 1254 | t) | ||
| 1255 | (setq comment-start-place (point)))))) | ||
| 1256 | ;; Inside a comment: fill one comment paragraph. | ||
| 1257 | (let ((fill-prefix | ||
| 1258 | ;; The prefix for each line of this paragraph | ||
| 1259 | ;; is the appropriate part of the start of this line, | ||
| 1260 | ;; up to the column at which text should be indented. | ||
| 1261 | (save-excursion | ||
| 1262 | (beginning-of-line) | ||
| 1263 | (if (looking-at "[ \t]*/\\*.*\\*/") | ||
| 1264 | (progn (re-search-forward comment-start-skip) | ||
| 1265 | (make-string (current-column) ?\ )) | ||
| 1266 | (if first-line (forward-line 1)) | ||
| 1267 | |||
| 1268 | (let ((line-width (progn (end-of-line) (current-column)))) | ||
| 1269 | (beginning-of-line) | ||
| 1270 | (prog1 | ||
| 1271 | (buffer-substring | ||
| 1272 | (point) | ||
| 1273 | |||
| 1274 | ;; How shall we decide where the end of the | ||
| 1275 | ;; fill-prefix is? | ||
| 1276 | (progn | ||
| 1277 | (beginning-of-line) | ||
| 1278 | (skip-chars-forward " \t*" (c-point 'eol)) | ||
| 1279 | ;; kludge alert, watch out for */, in | ||
| 1280 | ;; which case fill-prefix should *not* | ||
| 1281 | ;; be "*"! | ||
| 1282 | (if (and (eq (char-after) ?/) | ||
| 1283 | (eq (char-before) ?*)) | ||
| 1284 | (forward-char -1)) | ||
| 1285 | (point))) | ||
| 1286 | |||
| 1287 | ;; If the comment is only one line followed | ||
| 1288 | ;; by a blank line, calling move-to-column | ||
| 1289 | ;; above may have added some spaces and tabs | ||
| 1290 | ;; to the end of the line; the fill-paragraph | ||
| 1291 | ;; function will then delete it and the | ||
| 1292 | ;; newline following it, so we'll lose a | ||
| 1293 | ;; blank line when we shouldn't. So delete | ||
| 1294 | ;; anything move-to-column added to the end | ||
| 1295 | ;; of the line. We record the line width | ||
| 1296 | ;; instead of the position of the old line | ||
| 1297 | ;; end because move-to-column might break a | ||
| 1298 | ;; tab into spaces, and the new characters | ||
| 1299 | ;; introduced there shouldn't be deleted. | ||
| 1300 | |||
| 1301 | ;; If you can see a better way to do this, | ||
| 1302 | ;; please make the change. This seems very | ||
| 1303 | ;; messy to me. | ||
| 1304 | (delete-region (progn (move-to-column line-width) | ||
| 1305 | (point)) | ||
| 1306 | (progn (end-of-line) (point)))))))) | ||
| 1307 | |||
| 1308 | ;; Lines containing just a comment start or just an end | ||
| 1309 | ;; should not be filled into paragraphs they are next | ||
| 1310 | ;; to. | ||
| 1311 | (paragraph-start (concat paragraph-start re1)) | ||
| 1312 | (paragraph-separate (concat paragraph-separate re1)) | ||
| 1313 | (chars-to-delete 0) | ||
| 1314 | ) | ||
| 1315 | (save-restriction | ||
| 1316 | ;; Don't fill the comment together with the code | ||
| 1317 | ;; following it. So temporarily exclude everything | ||
| 1318 | ;; before the comment start, and everything after the | ||
| 1319 | ;; line where the comment ends. If comment-start-place | ||
| 1320 | ;; is non-nil, the comment starter is there. Otherwise, | ||
| 1321 | ;; point is inside the comment. | ||
| 1322 | (narrow-to-region (save-excursion | ||
| 1323 | (if comment-start-place | ||
| 1324 | (goto-char comment-start-place) | ||
| 1325 | (search-backward "/*")) | ||
| 1326 | (if (and (not c-hanging-comment-starter-p) | ||
| 1327 | (looking-at | ||
| 1328 | (concat c-comment-start-regexp | ||
| 1329 | "[ \t]*$"))) | ||
| 1330 | (forward-line 1)) | ||
| 1331 | ;; Protect text before the comment | ||
| 1332 | ;; start by excluding it. Add | ||
| 1333 | ;; spaces to bring back proper | ||
| 1334 | ;; indentation of that point. | ||
| 1335 | (let ((column (current-column))) | ||
| 1336 | (prog1 (point) | ||
| 1337 | (setq chars-to-delete column) | ||
| 1338 | (insert-char ?\ column)))) | ||
| 1339 | (save-excursion | ||
| 1340 | (if comment-start-place | ||
| 1341 | (goto-char (+ comment-start-place 2))) | ||
| 1342 | (search-forward "*/" nil 'move) | ||
| 1343 | (forward-line 1) | ||
| 1344 | (point))) | ||
| 1345 | (fill-paragraph arg) | ||
| 1346 | (save-excursion | ||
| 1347 | ;; Delete the chars we inserted to avoid clobbering | ||
| 1348 | ;; the stuff before the comment start. | ||
| 1349 | (goto-char (point-min)) | ||
| 1350 | (if (> chars-to-delete 0) | ||
| 1351 | (delete-region (point) (+ (point) chars-to-delete))) | ||
| 1352 | ;; Find the comment ender (should be on last line of | ||
| 1353 | ;; buffer, given the narrowing) and don't leave it on | ||
| 1354 | ;; its own line, unless that's the style that's desired. | ||
| 1355 | (goto-char (point-max)) | ||
| 1356 | (forward-line -1) | ||
| 1357 | (search-forward "*/" nil 'move) | ||
| 1358 | (beginning-of-line) | ||
| 1359 | (if (and c-hanging-comment-ender-p | ||
| 1360 | (looking-at "[ \t]*\\*/")) | ||
| 1361 | ;(delete-indentation))))) | ||
| 1362 | (let ((fill-column (+ fill-column 9999))) | ||
| 1363 | (forward-line -1) | ||
| 1364 | (fill-region-as-paragraph (point) (point-max)))))) | ||
| 1365 | t))))) | ||
| 1366 | |||
| 1367 | |||
| 1368 | (provide 'cc-cmds) | ||
| 1369 | ;;; cc-cmds.el ends here | ||
diff --git a/lisp/progmodes/cc-compat.el b/lisp/progmodes/cc-compat.el new file mode 100644 index 00000000000..3415515bfb8 --- /dev/null +++ b/lisp/progmodes/cc-compat.el | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | ;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion | ||
| 2 | |||
| 3 | ;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: 1994-1997 Barry A. Warsaw | ||
| 6 | ;; Maintainer: cc-mode-help@python.org | ||
| 7 | ;; Created: August 1994, split from cc-mode.el | ||
| 8 | ;; Version: 5.12 | ||
| 9 | ;; Keywords: c languages oop | ||
| 10 | |||
| 11 | ;; This file is part of GNU Emacs. | ||
| 12 | |||
| 13 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 14 | ;; it under the terms of the GNU General Public License as published by | ||
| 15 | ;; the Free Software Foundation; either version 2, or (at your option) | ||
| 16 | ;; any later version. | ||
| 17 | |||
| 18 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | ;; GNU General Public License for more details. | ||
| 22 | |||
| 23 | ;; You should have received a copy of the GNU General Public License | ||
| 24 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | ||
| 25 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 26 | ;; Boston, MA 02111-1307, USA. | ||
| 27 | |||
| 28 | ;;; Commentary: | ||
| 29 | ;; | ||
| 30 | ;; Boring old c-mode.el (BOCM) is confusion and brain melt. cc-mode.el | ||
| 31 | ;; is clarity of thought and purity of chi. If you are still unwilling | ||
| 32 | ;; to accept enlightenment, this might help, or it may prolong your | ||
| 33 | ;; agony. | ||
| 34 | ;; | ||
| 35 | ;; To use, add the following to your c-mode-hook: | ||
| 36 | ;; | ||
| 37 | ;; (require 'cc-compat) | ||
| 38 | ;; (c-set-style "BOCM") | ||
| 39 | |||
| 40 | ;;; Code: | ||
| 41 | |||
| 42 | (eval-when-compile | ||
| 43 | (require 'cc-styles) | ||
| 44 | (require 'cc-engine)) | ||
| 45 | |||
| 46 | |||
| 47 | ;; In case c-mode.el isn't loaded | ||
| 48 | (defvar c-indent-level 2 | ||
| 49 | "*Indentation of C statements with respect to containing block.") | ||
| 50 | (defvar c-brace-imaginary-offset 0 | ||
| 51 | "*Imagined indentation of a C open brace that actually follows a statement.") | ||
| 52 | (defvar c-brace-offset 0 | ||
| 53 | "*Extra indentation for braces, compared with other text in same context.") | ||
| 54 | (defvar c-argdecl-indent 5 | ||
| 55 | "*Indentation level of declarations of C function arguments.") | ||
| 56 | (defvar c-label-offset -2 | ||
| 57 | "*Offset of C label lines and case statements relative to usual indentation.") | ||
| 58 | (defvar c-continued-statement-offset 2 | ||
| 59 | "*Extra indent for lines not starting new statements.") | ||
| 60 | (defvar c-continued-brace-offset 0 | ||
| 61 | "*Extra indent for substatements that start with open-braces. | ||
| 62 | This is in addition to c-continued-statement-offset.") | ||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | ;; these offsets are taken by brute force testing c-mode.el, since | ||
| 67 | ;; there's no logic to what it does. | ||
| 68 | (let* ((offsets '(c-offsets-alist . | ||
| 69 | ((defun-block-intro . cc-block-intro-offset) | ||
| 70 | (statement-block-intro . cc-block-intro-offset) | ||
| 71 | (defun-open . 0) | ||
| 72 | (class-open . 0) | ||
| 73 | (inline-open . c-brace-offset) | ||
| 74 | (block-open . c-brace-offset) | ||
| 75 | (block-close . cc-block-close-offset) | ||
| 76 | (brace-list-open . c-brace-offset) | ||
| 77 | (substatement-open . cc-substatement-open-offset) | ||
| 78 | (substatement . c-continued-statement-offset) | ||
| 79 | (knr-argdecl-intro . c-argdecl-indent) | ||
| 80 | (case-label . c-label-offset) | ||
| 81 | (access-label . c-label-offset) | ||
| 82 | (label . c-label-offset) | ||
| 83 | )))) | ||
| 84 | (c-add-style "BOCM" offsets)) | ||
| 85 | |||
| 86 | |||
| 87 | (defun cc-block-intro-offset (langelem) | ||
| 88 | ;; taken directly from calculate-c-indent confusion | ||
| 89 | (save-excursion | ||
| 90 | (c-backward-syntactic-ws) | ||
| 91 | (if (eq (char-before) ?{) | ||
| 92 | (forward-char -1) | ||
| 93 | (goto-char (cdr langelem))) | ||
| 94 | (let* ((curcol (save-excursion | ||
| 95 | (goto-char (cdr langelem)) | ||
| 96 | (current-column))) | ||
| 97 | (bocm-lossage | ||
| 98 | ;; If no previous statement, indent it relative to line | ||
| 99 | ;; brace is on. For open brace in column zero, don't let | ||
| 100 | ;; statement start there too. If c-indent-level is zero, | ||
| 101 | ;; use c-brace-offset + c-continued-statement-offset | ||
| 102 | ;; instead. For open-braces not the first thing in a line, | ||
| 103 | ;; add in c-brace-imaginary-offset. | ||
| 104 | (+ (if (and (bolp) (zerop c-indent-level)) | ||
| 105 | (+ c-brace-offset c-continued-statement-offset) | ||
| 106 | c-indent-level) | ||
| 107 | ;; Move back over whitespace before the openbrace. If | ||
| 108 | ;; openbrace is not first nonwhite thing on the line, | ||
| 109 | ;; add the c-brace-imaginary-offset. | ||
| 110 | (progn (skip-chars-backward " \t") | ||
| 111 | (if (bolp) 0 c-brace-imaginary-offset)) | ||
| 112 | ;; If the openbrace is preceded by a parenthesized exp, | ||
| 113 | ;; move to the beginning of that; possibly a different | ||
| 114 | ;; line | ||
| 115 | (progn | ||
| 116 | (if (eq (char-before) ?\)) | ||
| 117 | (forward-sexp -1)) | ||
| 118 | ;; Get initial indentation of the line we are on. | ||
| 119 | (current-indentation))))) | ||
| 120 | (- bocm-lossage curcol)))) | ||
| 121 | |||
| 122 | |||
| 123 | (defun cc-block-close-offset (langelem) | ||
| 124 | (save-excursion | ||
| 125 | (let* ((here (point)) | ||
| 126 | bracep | ||
| 127 | (curcol (progn | ||
| 128 | (goto-char (cdr langelem)) | ||
| 129 | (current-column))) | ||
| 130 | (bocm-lossage (progn | ||
| 131 | (goto-char (cdr langelem)) | ||
| 132 | (if (eq (char-after) ?{) | ||
| 133 | (setq bracep t) | ||
| 134 | (goto-char here) | ||
| 135 | (beginning-of-line) | ||
| 136 | (backward-up-list 1) | ||
| 137 | (forward-char 1) | ||
| 138 | (c-forward-syntactic-ws)) | ||
| 139 | (current-column)))) | ||
| 140 | (- bocm-lossage curcol | ||
| 141 | (if bracep 0 c-indent-level))))) | ||
| 142 | |||
| 143 | |||
| 144 | (defun cc-substatement-open-offset (langelem) | ||
| 145 | (+ c-continued-statement-offset c-continued-brace-offset)) | ||
| 146 | |||
| 147 | |||
| 148 | (provide 'cc-compat) | ||
| 149 | ;;; cc-compat.el ends here | ||
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el new file mode 100644 index 00000000000..354ba3508ad --- /dev/null +++ b/lisp/progmodes/cc-defs.el | |||
| @@ -0,0 +1,185 @@ | |||
| 1 | ;;; cc-defs.el --- definitions for 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.12 | ||
| 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 | ;; Figure out what features this Emacs has | ||
| 32 | (defconst c-emacs-features | ||
| 33 | (let ((infodock-p (boundp 'infodock-version)) | ||
| 34 | (comments | ||
| 35 | ;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags. | ||
| 36 | ;; Emacs 19 uses a 1-bit flag. We will have to set up our | ||
| 37 | ;; syntax tables differently to handle this. | ||
| 38 | (let ((table (copy-syntax-table)) | ||
| 39 | entry) | ||
| 40 | (modify-syntax-entry ?a ". 12345678" table) | ||
| 41 | (cond | ||
| 42 | ;; XEmacs 19, and beyond Emacs 19.34 | ||
| 43 | ((arrayp table) | ||
| 44 | (setq entry (aref table ?a)) | ||
| 45 | ;; In Emacs, table entries are cons cells | ||
| 46 | (if (consp entry) (setq entry (car entry)))) | ||
| 47 | ;; XEmacs 20 | ||
| 48 | ((fboundp 'get-char-table) (setq entry (get-char-table ?a table))) | ||
| 49 | ;; before and including Emacs 19.34 | ||
| 50 | ((and (fboundp 'char-table-p) | ||
| 51 | (char-table-p table)) | ||
| 52 | (setq entry (car (char-table-range table [?a])))) | ||
| 53 | ;; incompatible | ||
| 54 | (t (error "CC Mode is incompatible with this version of Emacs"))) | ||
| 55 | (if (= (logand (lsh entry -16) 255) 255) | ||
| 56 | '8-bit | ||
| 57 | '1-bit)))) | ||
| 58 | (if infodock-p | ||
| 59 | (list comments 'infodock) | ||
| 60 | (list comments))) | ||
| 61 | "A list of features extant in the Emacs you are using. | ||
| 62 | There are many flavors of Emacs out there, each with different | ||
| 63 | features supporting those needed by CC Mode. Here's the current | ||
| 64 | supported list, along with the values for this variable: | ||
| 65 | |||
| 66 | XEmacs 19: (8-bit) | ||
| 67 | XEmacs 20: (8-bit) | ||
| 68 | Emacs 19: (1-bit) | ||
| 69 | |||
| 70 | Infodock (based on XEmacs) has an additional symbol on this list: | ||
| 71 | 'infodock.") | ||
| 72 | |||
| 73 | |||
| 74 | |||
| 75 | (defsubst c-point (position) | ||
| 76 | ;; Returns the value of point at certain commonly referenced POSITIONs. | ||
| 77 | ;; POSITION can be one of the following symbols: | ||
| 78 | ;; | ||
| 79 | ;; bol -- beginning of line | ||
| 80 | ;; eol -- end of line | ||
| 81 | ;; bod -- beginning of defun | ||
| 82 | ;; boi -- back to indentation | ||
| 83 | ;; ionl -- indentation of next line | ||
| 84 | ;; iopl -- indentation of previous line | ||
| 85 | ;; bonl -- beginning of next line | ||
| 86 | ;; bopl -- beginning of previous line | ||
| 87 | ;; | ||
| 88 | ;; This function does not modify point or mark. | ||
| 89 | (let ((here (point))) | ||
| 90 | (cond | ||
| 91 | ((eq position 'bol) (beginning-of-line)) | ||
| 92 | ((eq position 'eol) (end-of-line)) | ||
| 93 | ((eq position 'bod) | ||
| 94 | (beginning-of-defun) | ||
| 95 | ;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at | ||
| 96 | ;; the open brace. | ||
| 97 | (and defun-prompt-regexp | ||
| 98 | (looking-at defun-prompt-regexp) | ||
| 99 | (goto-char (match-end 0))) | ||
| 100 | ) | ||
| 101 | ((eq position 'boi) (back-to-indentation)) | ||
| 102 | ((eq position 'bonl) (forward-line 1)) | ||
| 103 | ((eq position 'bopl) (forward-line -1)) | ||
| 104 | ((eq position 'iopl) | ||
| 105 | (forward-line -1) | ||
| 106 | (back-to-indentation)) | ||
| 107 | ((eq position 'ionl) | ||
| 108 | (forward-line 1) | ||
| 109 | (back-to-indentation)) | ||
| 110 | (t (error "unknown buffer position requested: %s" position)) | ||
| 111 | ) | ||
| 112 | (prog1 | ||
| 113 | (point) | ||
| 114 | (goto-char here)))) | ||
| 115 | |||
| 116 | (defmacro c-safe (&rest body) | ||
| 117 | ;; safely execute BODY, return nil if an error occurred | ||
| 118 | (` (condition-case nil | ||
| 119 | (progn (,@ body)) | ||
| 120 | (error nil)))) | ||
| 121 | |||
| 122 | (defmacro c-add-syntax (symbol &optional relpos) | ||
| 123 | ;; a simple macro to append the syntax in symbol to the syntax list. | ||
| 124 | ;; try to increase performance by using this macro | ||
| 125 | (` (setq syntax (cons (cons (, symbol) (, relpos)) syntax)))) | ||
| 126 | |||
| 127 | (defsubst c-auto-newline () | ||
| 128 | ;; if auto-newline feature is turned on, insert a newline character | ||
| 129 | ;; and return t, otherwise return nil. | ||
| 130 | (and c-auto-newline | ||
| 131 | (not (c-in-literal)) | ||
| 132 | (not (newline)))) | ||
| 133 | |||
| 134 | (defsubst c-intersect-lists (list alist) | ||
| 135 | ;; return the element of ALIST that matches the first element found | ||
| 136 | ;; in LIST. Uses assq. | ||
| 137 | (let (match) | ||
| 138 | (while (and list | ||
| 139 | (not (setq match (assq (car list) alist)))) | ||
| 140 | (setq list (cdr list))) | ||
| 141 | match)) | ||
| 142 | |||
| 143 | (defsubst c-lookup-lists (list alist1 alist2) | ||
| 144 | ;; first, find the first entry from LIST that is present in ALIST1, | ||
| 145 | ;; then find the entry in ALIST2 for that entry. | ||
| 146 | (assq (car (c-intersect-lists list alist1)) alist2)) | ||
| 147 | |||
| 148 | (defsubst c-langelem-col (langelem &optional preserve-point) | ||
| 149 | ;; convenience routine to return the column of langelem's relpos. | ||
| 150 | ;; Leaves point at the relpos unless preserve-point is non-nil. | ||
| 151 | (let ((here (point))) | ||
| 152 | (goto-char (cdr langelem)) | ||
| 153 | (prog1 (current-column) | ||
| 154 | (if preserve-point | ||
| 155 | (goto-char here)) | ||
| 156 | ))) | ||
| 157 | |||
| 158 | (defsubst c-update-modeline () | ||
| 159 | ;; set the c-auto-hungry-string for the correct designation on the modeline | ||
| 160 | (setq c-auto-hungry-string | ||
| 161 | (if c-auto-newline | ||
| 162 | (if c-hungry-delete-key "/ah" "/a") | ||
| 163 | (if c-hungry-delete-key "/h" nil))) | ||
| 164 | (force-mode-line-update)) | ||
| 165 | |||
| 166 | (defsubst c-keep-region-active () | ||
| 167 | ;; Do whatever is necessary to keep the region active in XEmacs. | ||
| 168 | ;; Ignore byte-compiler warnings you might see. This is not needed | ||
| 169 | ;; for Emacs. | ||
| 170 | (and (boundp 'zmacs-region-stays) | ||
| 171 | (setq zmacs-region-stays t))) | ||
| 172 | |||
| 173 | (defsubst c-load-all () | ||
| 174 | ;; make sure all necessary components of CC Mode are loaded in. | ||
| 175 | (require 'cc-vars) | ||
| 176 | (require 'cc-engine) | ||
| 177 | (require 'cc-langs) | ||
| 178 | (require 'cc-menus) | ||
| 179 | (require 'cc-align) | ||
| 180 | (require 'cc-styles) | ||
| 181 | (require 'cc-cmds)) | ||
| 182 | |||
| 183 | |||
| 184 | (provide 'cc-defs) | ||
| 185 | ;;; cc-defs.el ends here | ||
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el new file mode 100644 index 00000000000..3ac0ed52b74 --- /dev/null +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -0,0 +1,1704 @@ | |||
| 1 | ;;; cc-engine.el --- core syntax guessing engine for 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.12 | ||
| 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 | ;; WARNING: Be *exceptionally* careful about modifications to this | ||
| 32 | ;; function! Much of CC Mode depends on this Doing The Right Thing. | ||
| 33 | ;; If you break it you will be sorry. | ||
| 34 | |||
| 35 | (defun c-beginning-of-statement-1 (&optional lim) | ||
| 36 | ;; move to the start of the current statement, or the previous | ||
| 37 | ;; statement if already at the beginning of one. | ||
| 38 | (let ((firstp t) | ||
| 39 | (substmt-p t) | ||
| 40 | donep c-in-literal-cache | ||
| 41 | ;; KLUDGE ALERT: maybe-labelp is used to pass information | ||
| 42 | ;; between c-crosses-statement-barrier-p and | ||
| 43 | ;; c-beginning-of-statement-1. A better way should be | ||
| 44 | ;; implemented. | ||
| 45 | maybe-labelp saved | ||
| 46 | (last-begin (point))) | ||
| 47 | ;; first check for bare semicolon | ||
| 48 | (if (and (progn (c-backward-syntactic-ws lim) | ||
| 49 | (eq (char-before) ?\;)) | ||
| 50 | (c-safe (progn (forward-char -1) | ||
| 51 | (setq saved (point)) | ||
| 52 | t)) | ||
| 53 | (progn (c-backward-syntactic-ws lim) | ||
| 54 | (memq (char-before) '(?\; ?{ ?} ?:))) | ||
| 55 | ) | ||
| 56 | (setq last-begin saved) | ||
| 57 | (goto-char last-begin) | ||
| 58 | (while (not donep) | ||
| 59 | ;; stop at beginning of buffer | ||
| 60 | (if (bobp) (setq donep t) | ||
| 61 | ;; go backwards one balanced expression, but be careful of | ||
| 62 | ;; unbalanced paren being reached | ||
| 63 | (if (not (c-safe (progn (backward-sexp 1) t))) | ||
| 64 | (progn | ||
| 65 | (if firstp | ||
| 66 | (backward-up-list 1) | ||
| 67 | (goto-char last-begin)) | ||
| 68 | ;; skip over any unary operators, or other special | ||
| 69 | ;; characters appearing at front of identifier | ||
| 70 | (save-excursion | ||
| 71 | (c-backward-syntactic-ws lim) | ||
| 72 | (skip-chars-backward "-+!*&:.~ \t\n") | ||
| 73 | (if (eq (char-before) ?\() | ||
| 74 | (setq last-begin (point)))) | ||
| 75 | (goto-char last-begin) | ||
| 76 | (setq last-begin (point) | ||
| 77 | donep t))) | ||
| 78 | |||
| 79 | (setq maybe-labelp nil) | ||
| 80 | ;; see if we're in a literal. if not, then this bufpos may be | ||
| 81 | ;; a candidate for stopping | ||
| 82 | (cond | ||
| 83 | ;; CASE 0: did we hit the error condition above? | ||
| 84 | (donep) | ||
| 85 | ;; CASE 1: are we in a literal? | ||
| 86 | ((eq (c-in-literal lim) 'pound) | ||
| 87 | (beginning-of-line)) | ||
| 88 | ;; CASE 2: some other kind of literal? | ||
| 89 | ((c-in-literal lim)) | ||
| 90 | ;; CASE 3: are we looking at a conditional keyword? | ||
| 91 | ((or (looking-at c-conditional-key) | ||
| 92 | (and (eq (char-after) ?\() | ||
| 93 | (save-excursion | ||
| 94 | (forward-sexp 1) | ||
| 95 | (c-forward-syntactic-ws) | ||
| 96 | (not (eq (char-after) ?\;))) | ||
| 97 | (let ((here (point)) | ||
| 98 | (foundp (progn | ||
| 99 | (c-backward-syntactic-ws lim) | ||
| 100 | (forward-word -1) | ||
| 101 | (and lim | ||
| 102 | (<= lim (point)) | ||
| 103 | (not (c-in-literal lim)) | ||
| 104 | (looking-at c-conditional-key) | ||
| 105 | )))) | ||
| 106 | ;; did we find a conditional? | ||
| 107 | (if (not foundp) | ||
| 108 | (goto-char here)) | ||
| 109 | foundp))) | ||
| 110 | ;; are we in the middle of an else-if clause? | ||
| 111 | (if (save-excursion | ||
| 112 | (and (not substmt-p) | ||
| 113 | (c-safe (progn (forward-sexp -1) t)) | ||
| 114 | (looking-at "\\<else\\>[ \t\n]+\\<if\\>") | ||
| 115 | (not (c-in-literal lim)))) | ||
| 116 | (progn | ||
| 117 | (forward-sexp -1) | ||
| 118 | (c-backward-to-start-of-if lim))) | ||
| 119 | ;; are we sitting at an else clause, that we are not a | ||
| 120 | ;; substatement of? | ||
| 121 | (if (and (not substmt-p) | ||
| 122 | (looking-at "\\<else\\>[^_]")) | ||
| 123 | (c-backward-to-start-of-if lim)) | ||
| 124 | ;; are we sitting at the while of a do-while? | ||
| 125 | (if (and (looking-at "\\<while\\>[^_]") | ||
| 126 | (c-backward-to-start-of-do lim)) | ||
| 127 | (setq substmt-p nil)) | ||
| 128 | (setq last-begin (point) | ||
| 129 | donep substmt-p)) | ||
| 130 | ;; CASE 4: are we looking at a label? | ||
| 131 | ((looking-at c-label-key)) | ||
| 132 | ;; CASE 5: is this the first time we're checking? | ||
| 133 | (firstp (setq firstp nil | ||
| 134 | substmt-p (not (c-crosses-statement-barrier-p | ||
| 135 | (point) last-begin)) | ||
| 136 | last-begin (point))) | ||
| 137 | ;; CASE 6: have we crossed a statement barrier? | ||
| 138 | ((c-crosses-statement-barrier-p (point) last-begin) | ||
| 139 | (setq donep t)) | ||
| 140 | ;; CASE 7: ignore labels | ||
| 141 | ((and maybe-labelp | ||
| 142 | (or (and c-access-key (looking-at c-access-key)) | ||
| 143 | ;; with switch labels, we have to go back further | ||
| 144 | ;; to try to pick up the case or default | ||
| 145 | ;; keyword. Potential bogosity alert: we assume | ||
| 146 | ;; `case' or `default' is first thing on line | ||
| 147 | (let ((here (point))) | ||
| 148 | (beginning-of-line) | ||
| 149 | (c-forward-syntactic-ws) | ||
| 150 | (if (looking-at c-switch-label-key) | ||
| 151 | t | ||
| 152 | (goto-char here) | ||
| 153 | nil)) | ||
| 154 | (looking-at c-label-key)))) | ||
| 155 | ;; CASE 8: ObjC or Java method def | ||
| 156 | ((and c-method-key | ||
| 157 | (setq last-begin (c-in-method-def-p))) | ||
| 158 | (setq donep t)) | ||
| 159 | ;; CASE 9: nothing special | ||
| 160 | (t (setq last-begin (point))) | ||
| 161 | )))) | ||
| 162 | (goto-char last-begin) | ||
| 163 | ;; we always do want to skip over non-whitespace modifier | ||
| 164 | ;; characters that didn't get skipped above | ||
| 165 | (skip-chars-backward "-+!*&:.~" (c-point 'boi)))) | ||
| 166 | |||
| 167 | (defun c-end-of-statement-1 () | ||
| 168 | (condition-case () | ||
| 169 | (progn | ||
| 170 | (while (and (not (eobp)) | ||
| 171 | (let ((beg (point))) | ||
| 172 | (forward-sexp 1) | ||
| 173 | (let ((end (point))) | ||
| 174 | (save-excursion | ||
| 175 | (goto-char beg) | ||
| 176 | (not (re-search-forward "[;{}]" end t))))))) | ||
| 177 | (re-search-backward "[;}]") | ||
| 178 | (forward-char 1)) | ||
| 179 | (error | ||
| 180 | (let ((beg (point))) | ||
| 181 | (backward-up-list -1) | ||
| 182 | (let ((end (point))) | ||
| 183 | (goto-char beg) | ||
| 184 | (search-forward ";" end 'move)))))) | ||
| 185 | |||
| 186 | |||
| 187 | |||
| 188 | (defun c-crosses-statement-barrier-p (from to) | ||
| 189 | ;; Does buffer positions FROM to TO cross a C statement boundary? | ||
| 190 | (let ((here (point)) | ||
| 191 | (lim from) | ||
| 192 | crossedp) | ||
| 193 | (condition-case () | ||
| 194 | (progn | ||
| 195 | (goto-char from) | ||
| 196 | (while (and (not crossedp) | ||
| 197 | (< (point) to)) | ||
| 198 | (skip-chars-forward "^;{}:" to) | ||
| 199 | (if (not (c-in-literal lim)) | ||
| 200 | (progn | ||
| 201 | (if (memq (char-after) '(?\; ?{ ?})) | ||
| 202 | (setq crossedp t) | ||
| 203 | (if (eq (char-after) ?:) | ||
| 204 | (setq maybe-labelp t)) | ||
| 205 | (forward-char 1)) | ||
| 206 | (setq lim (point))) | ||
| 207 | (forward-char 1)))) | ||
| 208 | (error (setq crossedp nil))) | ||
| 209 | (goto-char here) | ||
| 210 | crossedp)) | ||
| 211 | |||
| 212 | |||
| 213 | ;; Skipping of "syntactic whitespace", defined as lexical whitespace, | ||
| 214 | ;; C and C++ style comments, and preprocessor directives. Search no | ||
| 215 | ;; farther back or forward than optional LIM. If LIM is omitted, | ||
| 216 | ;; `beginning-of-defun' is used for backward skipping, point-max is | ||
| 217 | ;; used for forward skipping. | ||
| 218 | |||
| 219 | (defun c-forward-syntactic-ws (&optional lim) | ||
| 220 | ;; Forward skip of syntactic whitespace for Emacs 19. | ||
| 221 | (save-restriction | ||
| 222 | (let* ((lim (or lim (point-max))) | ||
| 223 | (here lim) | ||
| 224 | (hugenum (point-max))) | ||
| 225 | (narrow-to-region lim (point)) | ||
| 226 | (while (/= here (point)) | ||
| 227 | (setq here (point)) | ||
| 228 | (forward-comment hugenum) | ||
| 229 | ;; skip preprocessor directives | ||
| 230 | (if (and (eq (char-after) ?#) | ||
| 231 | (= (c-point 'boi) (point))) | ||
| 232 | (end-of-line) | ||
| 233 | ))))) | ||
| 234 | |||
| 235 | (defun c-backward-syntactic-ws (&optional lim) | ||
| 236 | ;; Backward skip over syntactic whitespace for Emacs 19. | ||
| 237 | (save-restriction | ||
| 238 | (let* ((lim (or lim (c-point 'bod))) | ||
| 239 | (here lim) | ||
| 240 | (hugenum (- (point-max)))) | ||
| 241 | (if (< lim (point)) | ||
| 242 | (progn | ||
| 243 | (narrow-to-region lim (point)) | ||
| 244 | (while (/= here (point)) | ||
| 245 | (setq here (point)) | ||
| 246 | (forward-comment hugenum) | ||
| 247 | (if (eq (c-in-literal lim) 'pound) | ||
| 248 | (beginning-of-line)) | ||
| 249 | ))) | ||
| 250 | ))) | ||
| 251 | |||
| 252 | |||
| 253 | ;; Return `c' if in a C-style comment, `c++' if in a C++ style | ||
| 254 | ;; comment, `string' if in a string literal, `pound' if on a | ||
| 255 | ;; preprocessor line, or nil if not in a comment at all. Optional LIM | ||
| 256 | ;; is used as the backward limit of the search. If omitted, or nil, | ||
| 257 | ;; `beginning-of-defun' is used." | ||
| 258 | |||
| 259 | (defun c-in-literal (&optional lim) | ||
| 260 | ;; Determine if point is in a C++ literal. we cache the last point | ||
| 261 | ;; calculated if the cache is enabled | ||
| 262 | (if (and (boundp 'c-in-literal-cache) | ||
| 263 | c-in-literal-cache | ||
| 264 | (= (point) (aref c-in-literal-cache 0))) | ||
| 265 | (aref c-in-literal-cache 1) | ||
| 266 | (let ((rtn (save-excursion | ||
| 267 | (let* ((lim (or lim (c-point 'bod))) | ||
| 268 | (here (point)) | ||
| 269 | (state (parse-partial-sexp lim (point)))) | ||
| 270 | (cond | ||
| 271 | ((nth 3 state) 'string) | ||
| 272 | ((nth 4 state) (if (nth 7 state) 'c++ 'c)) | ||
| 273 | ((progn | ||
| 274 | (goto-char here) | ||
| 275 | (beginning-of-line) | ||
| 276 | (looking-at "[ \t]*#")) | ||
| 277 | 'pound) | ||
| 278 | (t nil)))))) | ||
| 279 | ;; cache this result if the cache is enabled | ||
| 280 | (and (boundp 'c-in-literal-cache) | ||
| 281 | (setq c-in-literal-cache (vector (point) rtn))) | ||
| 282 | rtn))) | ||
| 283 | |||
| 284 | |||
| 285 | ;; utilities for moving and querying around syntactic elements | ||
| 286 | (defvar c-parsing-error nil) | ||
| 287 | |||
| 288 | (defun c-parse-state () | ||
| 289 | ;; Finds and records all open parens between some important point | ||
| 290 | ;; earlier in the file and point. | ||
| 291 | ;; | ||
| 292 | ;; if there's a state cache, return it | ||
| 293 | (setq c-parsing-error nil) | ||
| 294 | (if (boundp 'c-state-cache) c-state-cache | ||
| 295 | (let* (at-bob | ||
| 296 | (pos (save-excursion | ||
| 297 | ;; go back 2 bods, but ignore any bogus positions | ||
| 298 | ;; returned by beginning-of-defun (i.e. open paren | ||
| 299 | ;; in column zero) | ||
| 300 | (let ((cnt 2)) | ||
| 301 | (while (not (or at-bob (zerop cnt))) | ||
| 302 | (beginning-of-defun) | ||
| 303 | (if (eq (char-after) ?\{) | ||
| 304 | (setq cnt (1- cnt))) | ||
| 305 | (if (bobp) | ||
| 306 | (setq at-bob t)))) | ||
| 307 | (point))) | ||
| 308 | (here (save-excursion | ||
| 309 | ;;(skip-chars-forward " \t}") | ||
| 310 | (point))) | ||
| 311 | (last-bod pos) (last-pos pos) | ||
| 312 | placeholder state sexp-end) | ||
| 313 | ;; cache last bod position | ||
| 314 | (while (catch 'backup-bod | ||
| 315 | (setq state nil) | ||
| 316 | (while (and pos (< pos here)) | ||
| 317 | (setq last-pos pos) | ||
| 318 | (if (and (setq pos (c-safe (scan-lists pos 1 -1))) | ||
| 319 | (<= pos here)) | ||
| 320 | (progn | ||
| 321 | (setq sexp-end (c-safe (scan-sexps (1- pos) 1))) | ||
| 322 | (if (and sexp-end | ||
| 323 | (<= sexp-end here)) | ||
| 324 | ;; we want to record both the start and end | ||
| 325 | ;; of this sexp, but we only want to record | ||
| 326 | ;; the last-most of any of them before here | ||
| 327 | (progn | ||
| 328 | (if (eq (char-after (1- pos)) ?\{) | ||
| 329 | (setq state (cons (cons (1- pos) sexp-end) | ||
| 330 | (if (consp (car state)) | ||
| 331 | (cdr state) | ||
| 332 | state)))) | ||
| 333 | (setq pos sexp-end)) | ||
| 334 | ;; we're contained in this sexp so put pos on | ||
| 335 | ;; front of list | ||
| 336 | (setq state (cons (1- pos) state)))) | ||
| 337 | ;; something bad happened. check to see if we | ||
| 338 | ;; crossed an unbalanced close brace. if so, we | ||
| 339 | ;; didn't really find the right `important bufpos' | ||
| 340 | ;; so lets back up and try again | ||
| 341 | (if (and (not pos) (not at-bob) | ||
| 342 | (setq placeholder | ||
| 343 | (c-safe (scan-lists last-pos 1 1))) | ||
| 344 | ;;(char-after (1- placeholder)) | ||
| 345 | (<= placeholder here) | ||
| 346 | (eq (char-after (1- placeholder)) ?\})) | ||
| 347 | (while t | ||
| 348 | (setq last-bod (c-safe (scan-lists last-bod -1 1))) | ||
| 349 | (if (not last-bod) | ||
| 350 | (progn | ||
| 351 | ;; bogus, but what can we do here? | ||
| 352 | (setq c-parsing-error (1- placeholder)) | ||
| 353 | (throw 'backup-bod nil)) | ||
| 354 | (setq at-bob (= last-bod (point-min)) | ||
| 355 | pos last-bod) | ||
| 356 | (if (= (char-after last-bod) ?\{) | ||
| 357 | (throw 'backup-bod t))) | ||
| 358 | )) ;end-if | ||
| 359 | )) ;end-while | ||
| 360 | nil)) | ||
| 361 | state))) | ||
| 362 | |||
| 363 | (defun c-whack-state (bufpos state) | ||
| 364 | ;; whack off any state information that appears on STATE which lies | ||
| 365 | ;; after the bounds of BUFPOS. | ||
| 366 | (let (newstate car) | ||
| 367 | (while state | ||
| 368 | (setq car (car state) | ||
| 369 | state (cdr state)) | ||
| 370 | (if (consp car) | ||
| 371 | ;; just check the car, because in a balanced brace | ||
| 372 | ;; expression, it must be impossible for the corresponding | ||
| 373 | ;; close brace to be before point, but the open brace to be | ||
| 374 | ;; after. | ||
| 375 | (if (<= bufpos (car car)) | ||
| 376 | nil ; whack it off | ||
| 377 | ;; its possible that the open brace is before bufpos, but | ||
| 378 | ;; the close brace is after. In that case, convert this | ||
| 379 | ;; to a non-cons element. | ||
| 380 | (if (<= bufpos (cdr car)) | ||
| 381 | (setq newstate (append newstate (list (car car)))) | ||
| 382 | ;; we know that both the open and close braces are | ||
| 383 | ;; before bufpos, so we also know that everything else | ||
| 384 | ;; on state is before bufpos, so we can glom up the | ||
| 385 | ;; whole thing and exit. | ||
| 386 | (setq newstate (append newstate (list car) state) | ||
| 387 | state nil))) | ||
| 388 | (if (<= bufpos car) | ||
| 389 | nil ; whack it off | ||
| 390 | ;; it's before bufpos, so everything else should too | ||
| 391 | (setq newstate (append newstate (list car) state) | ||
| 392 | state nil)))) | ||
| 393 | newstate)) | ||
| 394 | |||
| 395 | (defun c-hack-state (bufpos which state) | ||
| 396 | ;; Using BUFPOS buffer position, and WHICH (must be 'open or | ||
| 397 | ;; 'close), hack the c-parse-state STATE and return the results. | ||
| 398 | (if (eq which 'open) | ||
| 399 | (let ((car (car state))) | ||
| 400 | (if (or (null car) | ||
| 401 | (consp car) | ||
| 402 | (/= bufpos car)) | ||
| 403 | (cons bufpos state) | ||
| 404 | state)) | ||
| 405 | (if (not (eq which 'close)) | ||
| 406 | (error "c-hack-state, bad argument: %s" which)) | ||
| 407 | ;; 'close brace | ||
| 408 | (let ((car (car state)) | ||
| 409 | (cdr (cdr state))) | ||
| 410 | (if (consp car) | ||
| 411 | (setq car (car cdr) | ||
| 412 | cdr (cdr cdr))) | ||
| 413 | ;; TBD: is this test relevant??? | ||
| 414 | (if (consp car) | ||
| 415 | state ;on error, don't change | ||
| 416 | ;; watch out for balanced expr already on cdr of list | ||
| 417 | (cons (cons car bufpos) | ||
| 418 | (if (consp (car cdr)) | ||
| 419 | (cdr cdr) cdr)) | ||
| 420 | )))) | ||
| 421 | |||
| 422 | (defun c-adjust-state (from to shift state) | ||
| 423 | ;; Adjust all points in state that lie in the region FROM..TO by | ||
| 424 | ;; SHIFT amount (as would be returned by c-indent-line). | ||
| 425 | (mapcar | ||
| 426 | (function | ||
| 427 | (lambda (e) | ||
| 428 | (if (consp e) | ||
| 429 | (let ((car (car e)) | ||
| 430 | (cdr (cdr e))) | ||
| 431 | (if (and (<= from car) (< car to)) | ||
| 432 | (setcar e (+ shift car))) | ||
| 433 | (if (and (<= from cdr) (< cdr to)) | ||
| 434 | (setcdr e (+ shift cdr)))) | ||
| 435 | (if (and (<= from e) (< e to)) | ||
| 436 | (setq e (+ shift e)))) | ||
| 437 | e)) | ||
| 438 | state)) | ||
| 439 | |||
| 440 | |||
| 441 | (defun c-beginning-of-inheritance-list (&optional lim) | ||
| 442 | ;; Go to the first non-whitespace after the colon that starts a | ||
| 443 | ;; multiple inheritance introduction. Optional LIM is the farthest | ||
| 444 | ;; back we should search. | ||
| 445 | (let ((lim (or lim (c-point 'bod))) | ||
| 446 | (placeholder (progn | ||
| 447 | (back-to-indentation) | ||
| 448 | (point)))) | ||
| 449 | (c-backward-syntactic-ws lim) | ||
| 450 | (while (and (> (point) lim) | ||
| 451 | (memq (char-before) '(?, ?:)) | ||
| 452 | (progn | ||
| 453 | (beginning-of-line) | ||
| 454 | (setq placeholder (point)) | ||
| 455 | (skip-chars-forward " \t") | ||
| 456 | (not (looking-at c-class-key)) | ||
| 457 | )) | ||
| 458 | (c-backward-syntactic-ws lim)) | ||
| 459 | (goto-char placeholder) | ||
| 460 | (skip-chars-forward "^:" (c-point 'eol)))) | ||
| 461 | |||
| 462 | (defun c-beginning-of-macro (&optional lim) | ||
| 463 | ;; Go to the beginning of the macro. Right now we don't support | ||
| 464 | ;; multi-line macros too well | ||
| 465 | (back-to-indentation)) | ||
| 466 | |||
| 467 | (defun c-in-method-def-p () | ||
| 468 | ;; Return nil if we aren't in a method definition, otherwise the | ||
| 469 | ;; position of the initial [+-]. | ||
| 470 | (save-excursion | ||
| 471 | (beginning-of-line) | ||
| 472 | (and c-method-key | ||
| 473 | (looking-at c-method-key) | ||
| 474 | (point)) | ||
| 475 | )) | ||
| 476 | |||
| 477 | (defun c-just-after-func-arglist-p (&optional containing) | ||
| 478 | ;; Return t if we are between a function's argument list closing | ||
| 479 | ;; paren and its opening brace. Note that the list close brace | ||
| 480 | ;; could be followed by a "const" specifier or a member init hanging | ||
| 481 | ;; colon. Optional CONTAINING is position of containing s-exp open | ||
| 482 | ;; brace. If not supplied, point is used as search start. | ||
| 483 | (save-excursion | ||
| 484 | (c-backward-syntactic-ws) | ||
| 485 | (let ((checkpoint (or containing (point)))) | ||
| 486 | (goto-char checkpoint) | ||
| 487 | ;; could be looking at const specifier | ||
| 488 | (if (and (eq (char-before) ?t) | ||
| 489 | (forward-word -1) | ||
| 490 | (looking-at "\\<const\\>")) | ||
| 491 | (c-backward-syntactic-ws) | ||
| 492 | ;; otherwise, we could be looking at a hanging member init | ||
| 493 | ;; colon | ||
| 494 | (goto-char checkpoint) | ||
| 495 | (if (and (eq (char-before) ?:) | ||
| 496 | (progn | ||
| 497 | (forward-char -1) | ||
| 498 | (c-backward-syntactic-ws) | ||
| 499 | (looking-at "[ \t\n]*:\\([^:]+\\|$\\)"))) | ||
| 500 | nil | ||
| 501 | (goto-char checkpoint)) | ||
| 502 | ) | ||
| 503 | (and (eq (char-before) ?\)) | ||
| 504 | ;; check if we are looking at a method def | ||
| 505 | (or (not c-method-key) | ||
| 506 | (progn | ||
| 507 | (forward-sexp -1) | ||
| 508 | (forward-char -1) | ||
| 509 | (c-backward-syntactic-ws) | ||
| 510 | (not (or (memq (char-before) '(?- ?+)) | ||
| 511 | ;; or a class category | ||
| 512 | (progn | ||
| 513 | (forward-sexp -2) | ||
| 514 | (looking-at c-class-key)) | ||
| 515 | ))))) | ||
| 516 | ))) | ||
| 517 | |||
| 518 | ;; defuns to look backwards for things | ||
| 519 | (defun c-backward-to-start-of-do (&optional lim) | ||
| 520 | ;; Move to the start of the last "unbalanced" do expression. | ||
| 521 | ;; Optional LIM is the farthest back to search. If none is found, | ||
| 522 | ;; nil is returned and point is left unchanged, otherwise t is returned. | ||
| 523 | (let ((do-level 1) | ||
| 524 | (case-fold-search nil) | ||
| 525 | (lim (or lim (c-point 'bod))) | ||
| 526 | (here (point)) | ||
| 527 | foundp) | ||
| 528 | (while (not (zerop do-level)) | ||
| 529 | ;; we protect this call because trying to execute this when the | ||
| 530 | ;; while is not associated with a do will throw an error | ||
| 531 | (condition-case nil | ||
| 532 | (progn | ||
| 533 | (backward-sexp 1) | ||
| 534 | (cond | ||
| 535 | ((memq (c-in-literal lim) '(c c++))) | ||
| 536 | ((looking-at "while\\b[^_]") | ||
| 537 | (setq do-level (1+ do-level))) | ||
| 538 | ((looking-at "do\\b[^_]") | ||
| 539 | (if (zerop (setq do-level (1- do-level))) | ||
| 540 | (setq foundp t))) | ||
| 541 | ((<= (point) lim) | ||
| 542 | (setq do-level 0) | ||
| 543 | (goto-char lim)))) | ||
| 544 | (error | ||
| 545 | (goto-char lim) | ||
| 546 | (setq do-level 0)))) | ||
| 547 | (if (not foundp) | ||
| 548 | (goto-char here)) | ||
| 549 | foundp)) | ||
| 550 | |||
| 551 | (defun c-backward-to-start-of-if (&optional lim) | ||
| 552 | ;; Move to the start of the last "unbalanced" if and return t. If | ||
| 553 | ;; none is found, and we are looking at an if clause, nil is | ||
| 554 | ;; returned. If none is found and we are looking at an else clause, | ||
| 555 | ;; an error is thrown. | ||
| 556 | (let ((if-level 1) | ||
| 557 | (here (c-point 'bol)) | ||
| 558 | (case-fold-search nil) | ||
| 559 | (lim (or lim (c-point 'bod))) | ||
| 560 | (at-if (looking-at "if\\b[^_]"))) | ||
| 561 | (catch 'orphan-if | ||
| 562 | (while (and (not (bobp)) | ||
| 563 | (not (zerop if-level))) | ||
| 564 | (c-backward-syntactic-ws) | ||
| 565 | (condition-case nil | ||
| 566 | (backward-sexp 1) | ||
| 567 | (error | ||
| 568 | (if at-if | ||
| 569 | (throw 'orphan-if nil) | ||
| 570 | (error "No matching `if' found for `else' on line %d." | ||
| 571 | (1+ (count-lines 1 here)))))) | ||
| 572 | (cond | ||
| 573 | ((looking-at "else\\b[^_]") | ||
| 574 | (setq if-level (1+ if-level))) | ||
| 575 | ((looking-at "if\\b[^_]") | ||
| 576 | ;; check for else if... skip over | ||
| 577 | (let ((here (point))) | ||
| 578 | (c-safe (forward-sexp -1)) | ||
| 579 | (if (looking-at "\\<else\\>[ \t]+\\<if\\>") | ||
| 580 | nil | ||
| 581 | (setq if-level (1- if-level)) | ||
| 582 | (goto-char here)))) | ||
| 583 | ((< (point) lim) | ||
| 584 | (setq if-level 0) | ||
| 585 | (goto-char lim)) | ||
| 586 | )) | ||
| 587 | t))) | ||
| 588 | |||
| 589 | (defun c-skip-conditional () | ||
| 590 | ;; skip forward over conditional at point, including any predicate | ||
| 591 | ;; statements in parentheses. No error checking is performed. | ||
| 592 | (forward-sexp (cond | ||
| 593 | ;; else if() | ||
| 594 | ((looking-at "\\<else\\>[ \t]+\\<if\\>") 3) | ||
| 595 | ;; do, else, try, finally | ||
| 596 | ((looking-at "\\<\\(do\\|else\\|try\\|finally\\)\\>") 1) | ||
| 597 | ;; for, if, while, switch, catch, synchronized | ||
| 598 | (t 2)))) | ||
| 599 | |||
| 600 | (defun c-skip-case-statement-forward (state &optional lim) | ||
| 601 | ;; skip forward over case/default bodies, with optional maximal | ||
| 602 | ;; limit. if no next case body is found, nil is returned and point | ||
| 603 | ;; is not moved | ||
| 604 | (let ((lim (or lim (point-max))) | ||
| 605 | (here (point)) | ||
| 606 | donep foundp bufpos | ||
| 607 | (safepos (point)) | ||
| 608 | (balanced (car state))) | ||
| 609 | ;; search until we've passed the limit, or we've found our match | ||
| 610 | (while (and (< (point) lim) | ||
| 611 | (not donep)) | ||
| 612 | (setq safepos (point)) | ||
| 613 | ;; see if we can find a case statement, not in a literal | ||
| 614 | (if (and (re-search-forward c-switch-label-key lim 'move) | ||
| 615 | (setq bufpos (match-beginning 0)) | ||
| 616 | (not (c-in-literal safepos)) | ||
| 617 | (/= bufpos here)) | ||
| 618 | ;; if we crossed into a balanced sexp, we know the case is | ||
| 619 | ;; not part of our switch statement, so just bound over the | ||
| 620 | ;; sexp and keep looking. | ||
| 621 | (if (and (consp balanced) | ||
| 622 | (> bufpos (car balanced)) | ||
| 623 | (< bufpos (cdr balanced))) | ||
| 624 | (goto-char (cdr balanced)) | ||
| 625 | (goto-char bufpos) | ||
| 626 | (setq donep t | ||
| 627 | foundp t)))) | ||
| 628 | (if (not foundp) | ||
| 629 | (goto-char here)) | ||
| 630 | foundp)) | ||
| 631 | |||
| 632 | (defun c-search-uplist-for-classkey (brace-state) | ||
| 633 | ;; search for the containing class, returning a 2 element vector if | ||
| 634 | ;; found. aref 0 contains the bufpos of the class key, and aref 1 | ||
| 635 | ;; contains the bufpos of the open brace. | ||
| 636 | (if (null brace-state) | ||
| 637 | ;; no brace-state means we cannot be inside a class | ||
| 638 | nil | ||
| 639 | (let ((carcache (car brace-state)) | ||
| 640 | search-start search-end) | ||
| 641 | (if (consp carcache) | ||
| 642 | ;; a cons cell in the first element means that there is some | ||
| 643 | ;; balanced sexp before the current bufpos. this we can | ||
| 644 | ;; ignore. the nth 1 and nth 2 elements define for us the | ||
| 645 | ;; search boundaries | ||
| 646 | (setq search-start (nth 2 brace-state) | ||
| 647 | search-end (nth 1 brace-state)) | ||
| 648 | ;; if the car was not a cons cell then nth 0 and nth 1 define | ||
| 649 | ;; for us the search boundaries | ||
| 650 | (setq search-start (nth 1 brace-state) | ||
| 651 | search-end (nth 0 brace-state))) | ||
| 652 | ;; search-end cannot be a cons cell | ||
| 653 | (and (consp search-end) | ||
| 654 | (error "consp search-end: %s" search-end)) | ||
| 655 | ;; if search-end is nil, or if the search-end character isn't an | ||
| 656 | ;; open brace, we are definitely not in a class | ||
| 657 | (if (or (not search-end) | ||
| 658 | (< search-end (point-min)) | ||
| 659 | (not (eq (char-after search-end) ?{))) | ||
| 660 | nil | ||
| 661 | ;; now, we need to look more closely at search-start. if | ||
| 662 | ;; search-start is nil, then our start boundary is really | ||
| 663 | ;; point-min. | ||
| 664 | (if (not search-start) | ||
| 665 | (setq search-start (point-min)) | ||
| 666 | ;; if search-start is a cons cell, then we can start | ||
| 667 | ;; searching from the end of the balanced sexp just ahead of | ||
| 668 | ;; us | ||
| 669 | (if (consp search-start) | ||
| 670 | (setq search-start (cdr search-start)))) | ||
| 671 | ;; now we can do a quick regexp search from search-start to | ||
| 672 | ;; search-end and see if we can find a class key. watch for | ||
| 673 | ;; class like strings in literals | ||
| 674 | (save-excursion | ||
| 675 | (save-restriction | ||
| 676 | (goto-char search-start) | ||
| 677 | (let ((search-key (concat c-class-key "\\|extern[^_]")) | ||
| 678 | foundp class match-end) | ||
| 679 | (while (and (not foundp) | ||
| 680 | (progn | ||
| 681 | (c-forward-syntactic-ws) | ||
| 682 | (> search-end (point))) | ||
| 683 | (re-search-forward search-key search-end t)) | ||
| 684 | (setq class (match-beginning 0) | ||
| 685 | match-end (match-end 0)) | ||
| 686 | (if (c-in-literal search-start) | ||
| 687 | nil ; its in a comment or string, ignore | ||
| 688 | (goto-char class) | ||
| 689 | (skip-chars-forward " \t\n") | ||
| 690 | (setq foundp (vector (c-point 'boi) search-end)) | ||
| 691 | (cond | ||
| 692 | ;; check for embedded keywords | ||
| 693 | ((let ((char (char-after (1- class)))) | ||
| 694 | (and char | ||
| 695 | (memq (char-syntax char) '(?w ?_)))) | ||
| 696 | (goto-char match-end) | ||
| 697 | (setq foundp nil)) | ||
| 698 | ;; make sure we're really looking at the start of a | ||
| 699 | ;; class definition, and not a forward decl, return | ||
| 700 | ;; arg, template arg list, or an ObjC or Java method. | ||
| 701 | ((and c-method-key | ||
| 702 | (re-search-forward c-method-key search-end t)) | ||
| 703 | (setq foundp nil)) | ||
| 704 | ;; Its impossible to define a regexp for this, and | ||
| 705 | ;; nearly so to do it programmatically. | ||
| 706 | ;; | ||
| 707 | ;; ; picks up forward decls | ||
| 708 | ;; = picks up init lists | ||
| 709 | ;; ) picks up return types | ||
| 710 | ;; > picks up templates, but remember that we can | ||
| 711 | ;; inherit from templates! | ||
| 712 | ((let ((skipchars "^;=)")) | ||
| 713 | ;; try to see if we found the `class' keyword | ||
| 714 | ;; inside a template arg list | ||
| 715 | (save-excursion | ||
| 716 | (skip-chars-backward "^<>" search-start) | ||
| 717 | (if (eq (char-before) ?<) | ||
| 718 | (setq skipchars (concat skipchars ">")))) | ||
| 719 | (skip-chars-forward skipchars search-end) | ||
| 720 | (/= (point) search-end)) | ||
| 721 | (setq foundp nil)) | ||
| 722 | ))) | ||
| 723 | foundp)) | ||
| 724 | ))))) | ||
| 725 | |||
| 726 | (defun c-inside-bracelist-p (containing-sexp brace-state) | ||
| 727 | ;; return the buffer position of the beginning of the brace list | ||
| 728 | ;; statement if we're inside a brace list, otherwise return nil. | ||
| 729 | ;; CONTAINING-SEXP is the buffer pos of the innermost containing | ||
| 730 | ;; paren. BRACE-STATE is the remainder of the state of enclosing braces | ||
| 731 | ;; | ||
| 732 | ;; N.B.: This algorithm can potentially get confused by cpp macros | ||
| 733 | ;; places in inconvenient locations. Its a trade-off we make for | ||
| 734 | ;; speed. | ||
| 735 | (or | ||
| 736 | ;; this will pick up enum lists | ||
| 737 | (condition-case () | ||
| 738 | (save-excursion | ||
| 739 | (goto-char containing-sexp) | ||
| 740 | (forward-sexp -1) | ||
| 741 | (if (or (looking-at "enum[\t\n ]+") | ||
| 742 | (progn (forward-sexp -1) | ||
| 743 | (looking-at "enum[\t\n ]+"))) | ||
| 744 | (point))) | ||
| 745 | (error nil)) | ||
| 746 | ;; this will pick up array/aggregate init lists, even if they are nested. | ||
| 747 | (save-excursion | ||
| 748 | (let (bufpos failedp) | ||
| 749 | (while (and (not bufpos) | ||
| 750 | containing-sexp) | ||
| 751 | (if (consp containing-sexp) | ||
| 752 | (setq containing-sexp (car brace-state) | ||
| 753 | brace-state (cdr brace-state)) | ||
| 754 | ;; see if significant character just before brace is an equal | ||
| 755 | (goto-char containing-sexp) | ||
| 756 | (setq failedp nil) | ||
| 757 | (condition-case () | ||
| 758 | (progn | ||
| 759 | (forward-sexp -1) | ||
| 760 | (forward-sexp 1) | ||
| 761 | (c-forward-syntactic-ws containing-sexp)) | ||
| 762 | (error (setq failedp t))) | ||
| 763 | (if (or failedp (not (eq (char-after) ?=))) | ||
| 764 | ;; lets see if we're nested. find the most nested | ||
| 765 | ;; containing brace | ||
| 766 | (setq containing-sexp (car brace-state) | ||
| 767 | brace-state (cdr brace-state)) | ||
| 768 | ;; we've hit the beginning of the aggregate list | ||
| 769 | (c-beginning-of-statement-1 (c-most-enclosing-brace brace-state)) | ||
| 770 | (setq bufpos (point))) | ||
| 771 | )) | ||
| 772 | bufpos)) | ||
| 773 | )) | ||
| 774 | |||
| 775 | |||
| 776 | (defun c-most-enclosing-brace (state) | ||
| 777 | ;; return the bufpos of the most enclosing brace that hasn't been | ||
| 778 | ;; narrowed out by any enclosing class, or nil if none was found | ||
| 779 | (let (enclosingp) | ||
| 780 | (while (and state (not enclosingp)) | ||
| 781 | (setq enclosingp (car state) | ||
| 782 | state (cdr state)) | ||
| 783 | (if (consp enclosingp) | ||
| 784 | (setq enclosingp nil) | ||
| 785 | (if (> (point-min) enclosingp) | ||
| 786 | (setq enclosingp nil)) | ||
| 787 | (setq state nil))) | ||
| 788 | enclosingp)) | ||
| 789 | |||
| 790 | (defun c-least-enclosing-brace (state) | ||
| 791 | ;; return the bufpos of the least (highest) enclosing brace that | ||
| 792 | ;; hasn't been narrowed out by any enclosing class, or nil if none | ||
| 793 | ;; was found. | ||
| 794 | (c-most-enclosing-brace (nreverse state))) | ||
| 795 | |||
| 796 | (defun c-safe-position (bufpos state) | ||
| 797 | ;; return the closest known safe position higher up than point | ||
| 798 | (let ((safepos nil)) | ||
| 799 | (while state | ||
| 800 | (setq safepos | ||
| 801 | (if (consp (car state)) | ||
| 802 | (cdr (car state)) | ||
| 803 | (car state))) | ||
| 804 | (if (< safepos bufpos) | ||
| 805 | (setq state nil) | ||
| 806 | (setq state (cdr state)))) | ||
| 807 | safepos)) | ||
| 808 | |||
| 809 | (defun c-narrow-out-enclosing-class (state lim) | ||
| 810 | ;; narrow the buffer so that the enclosing class is hidden | ||
| 811 | (let (inclass-p) | ||
| 812 | (and state | ||
| 813 | (setq inclass-p (c-search-uplist-for-classkey state)) | ||
| 814 | (narrow-to-region | ||
| 815 | (progn | ||
| 816 | (goto-char (1+ (aref inclass-p 1))) | ||
| 817 | (skip-chars-forward " \t\n" lim) | ||
| 818 | ;; if point is now left of the class opening brace, we're | ||
| 819 | ;; hosed, so try a different tact | ||
| 820 | (if (<= (point) (aref inclass-p 1)) | ||
| 821 | (progn | ||
| 822 | (goto-char (1+ (aref inclass-p 1))) | ||
| 823 | (c-forward-syntactic-ws lim))) | ||
| 824 | (point)) | ||
| 825 | ;; end point is the end of the current line | ||
| 826 | (progn | ||
| 827 | (goto-char lim) | ||
| 828 | (c-point 'eol)))) | ||
| 829 | ;; return the class vector | ||
| 830 | inclass-p)) | ||
| 831 | |||
| 832 | |||
| 833 | ;; This function implements the main decision tree for determining the | ||
| 834 | ;; syntactic analysis of the current line of code. Yes, it's huge and | ||
| 835 | ;; bloated! | ||
| 836 | |||
| 837 | (defun c-guess-basic-syntax () | ||
| 838 | (save-excursion | ||
| 839 | (save-restriction | ||
| 840 | (beginning-of-line) | ||
| 841 | (let* ((indent-point (point)) | ||
| 842 | (case-fold-search nil) | ||
| 843 | (fullstate (c-parse-state)) | ||
| 844 | (state fullstate) | ||
| 845 | (in-method-intro-p (and (eq major-mode 'objc-mode) | ||
| 846 | c-method-key | ||
| 847 | (looking-at c-method-key))) | ||
| 848 | literal containing-sexp char-before-ip char-after-ip lim | ||
| 849 | syntax placeholder c-in-literal-cache inswitch-p | ||
| 850 | injava-inher | ||
| 851 | ;; narrow out any enclosing class or extern "C" block | ||
| 852 | (inclass-p (c-narrow-out-enclosing-class state indent-point)) | ||
| 853 | (inextern-p (and inclass-p | ||
| 854 | (save-excursion | ||
| 855 | (save-restriction | ||
| 856 | (widen) | ||
| 857 | (goto-char (aref inclass-p 0)) | ||
| 858 | (looking-at "extern[^_]"))))) | ||
| 859 | ) | ||
| 860 | |||
| 861 | ;; get the buffer position of the most nested opening brace, | ||
| 862 | ;; if there is one, and it hasn't been narrowed out | ||
| 863 | (save-excursion | ||
| 864 | (goto-char indent-point) | ||
| 865 | (skip-chars-forward " \t}") | ||
| 866 | (skip-chars-backward " \t") | ||
| 867 | (while (and state | ||
| 868 | (not in-method-intro-p) | ||
| 869 | (not containing-sexp)) | ||
| 870 | (setq containing-sexp (car state) | ||
| 871 | state (cdr state)) | ||
| 872 | (if (consp containing-sexp) | ||
| 873 | ;; if cdr == point, then containing sexp is the brace | ||
| 874 | ;; that opens the sexp we close | ||
| 875 | (if (= (cdr containing-sexp) (point)) | ||
| 876 | (setq containing-sexp (car containing-sexp)) | ||
| 877 | ;; otherwise, ignore this element | ||
| 878 | (setq containing-sexp nil)) | ||
| 879 | ;; ignore the bufpos if its been narrowed out by the | ||
| 880 | ;; containing class | ||
| 881 | (if (<= containing-sexp (point-min)) | ||
| 882 | (setq containing-sexp nil))))) | ||
| 883 | |||
| 884 | ;; set the limit on the farthest back we need to search | ||
| 885 | (setq lim (or containing-sexp | ||
| 886 | (if (consp (car fullstate)) | ||
| 887 | (cdr (car fullstate)) | ||
| 888 | nil) | ||
| 889 | (point-min))) | ||
| 890 | |||
| 891 | ;; cache char before and after indent point, and move point to | ||
| 892 | ;; the most likely position to perform the majority of tests | ||
| 893 | (goto-char indent-point) | ||
| 894 | (skip-chars-forward " \t") | ||
| 895 | (setq char-after-ip (char-after)) | ||
| 896 | (c-backward-syntactic-ws lim) | ||
| 897 | (setq char-before-ip (char-before)) | ||
| 898 | (goto-char indent-point) | ||
| 899 | (skip-chars-forward " \t") | ||
| 900 | |||
| 901 | ;; are we in a literal? | ||
| 902 | (setq literal (c-in-literal lim)) | ||
| 903 | |||
| 904 | ;; now figure out syntactic qualities of the current line | ||
| 905 | (cond | ||
| 906 | ;; CASE 1: in a string. | ||
| 907 | ((memq literal '(string)) | ||
| 908 | (c-add-syntax 'string (c-point 'bopl))) | ||
| 909 | ;; CASE 2: in a C or C++ style comment. | ||
| 910 | ((memq literal '(c c++)) | ||
| 911 | ;; we need to catch multi-paragraph C comments | ||
| 912 | (while (and (zerop (forward-line -1)) | ||
| 913 | (looking-at "^[ \t]*$"))) | ||
| 914 | (c-add-syntax literal (c-point 'boi))) | ||
| 915 | ;; CASE 3: in a cpp preprocessor | ||
| 916 | ((eq literal 'pound) | ||
| 917 | (c-beginning-of-macro lim) | ||
| 918 | (c-add-syntax 'cpp-macro (c-point 'boi))) | ||
| 919 | ;; CASE 4: in an objective-c method intro | ||
| 920 | (in-method-intro-p | ||
| 921 | (c-add-syntax 'objc-method-intro (c-point 'boi))) | ||
| 922 | ;; CASE 5: Line is at top level. | ||
| 923 | ((null containing-sexp) | ||
| 924 | (cond | ||
| 925 | ;; CASE 5A: we are looking at a defun, class, or | ||
| 926 | ;; inline-inclass method opening brace | ||
| 927 | ((eq char-after-ip ?{) | ||
| 928 | (cond | ||
| 929 | ;; CASE 5A.1: extern declaration | ||
| 930 | ((save-excursion | ||
| 931 | (goto-char indent-point) | ||
| 932 | (skip-chars-forward " \t") | ||
| 933 | (and (c-safe (progn (backward-sexp 2) t)) | ||
| 934 | (looking-at "extern[^_]") | ||
| 935 | (progn | ||
| 936 | (setq placeholder (point)) | ||
| 937 | (forward-sexp 1) | ||
| 938 | (c-forward-syntactic-ws) | ||
| 939 | (eq (char-after) ?\")))) | ||
| 940 | (goto-char placeholder) | ||
| 941 | (c-add-syntax 'extern-lang-open (c-point 'boi))) | ||
| 942 | ;; CASE 5A.2: we are looking at a class opening brace | ||
| 943 | ((save-excursion | ||
| 944 | (goto-char indent-point) | ||
| 945 | (skip-chars-forward " \t{") | ||
| 946 | ;; TBD: watch out! there could be a bogus | ||
| 947 | ;; c-state-cache in place when we get here. we have | ||
| 948 | ;; to go through much chicanery to ignore the cache. | ||
| 949 | ;; But of course, there may not be! BLECH! BOGUS! | ||
| 950 | (let ((decl | ||
| 951 | (if (boundp 'c-state-cache) | ||
| 952 | (let ((old-cache c-state-cache)) | ||
| 953 | (prog2 | ||
| 954 | (makunbound 'c-state-cache) | ||
| 955 | (c-search-uplist-for-classkey (c-parse-state)) | ||
| 956 | (setq c-state-cache old-cache))) | ||
| 957 | (c-search-uplist-for-classkey (c-parse-state)) | ||
| 958 | ))) | ||
| 959 | (and decl | ||
| 960 | (setq placeholder (aref decl 0))) | ||
| 961 | )) | ||
| 962 | (c-add-syntax 'class-open placeholder)) | ||
| 963 | ;; CASE 5A.3: brace list open | ||
| 964 | ((save-excursion | ||
| 965 | (c-beginning-of-statement-1 lim) | ||
| 966 | ;; c-b-o-s could have left us at point-min | ||
| 967 | (and (bobp) | ||
| 968 | (c-forward-syntactic-ws indent-point)) | ||
| 969 | (if (looking-at "typedef[^_]") | ||
| 970 | (progn (forward-sexp 1) | ||
| 971 | (c-forward-syntactic-ws indent-point))) | ||
| 972 | (setq placeholder (c-point 'boi)) | ||
| 973 | (and (or (looking-at "enum[ \t\n]+") | ||
| 974 | (eq char-before-ip ?=)) | ||
| 975 | (save-excursion | ||
| 976 | (skip-chars-forward "^;(" indent-point) | ||
| 977 | (not (memq (char-after) '(?\; ?\())) | ||
| 978 | ))) | ||
| 979 | (c-add-syntax 'brace-list-open placeholder)) | ||
| 980 | ;; CASE 5A.4: inline defun open | ||
| 981 | ((and inclass-p (not inextern-p)) | ||
| 982 | (c-add-syntax 'inline-open) | ||
| 983 | (c-add-syntax 'inclass (aref inclass-p 0))) | ||
| 984 | ;; CASE 5A.5: ordinary defun open | ||
| 985 | (t | ||
| 986 | (goto-char placeholder) | ||
| 987 | (c-add-syntax 'defun-open (c-point 'bol)) | ||
| 988 | ))) | ||
| 989 | ;; CASE 5B: first K&R arg decl or member init | ||
| 990 | ((c-just-after-func-arglist-p) | ||
| 991 | (cond | ||
| 992 | ;; CASE 5B.1: a member init | ||
| 993 | ((or (eq char-before-ip ?:) | ||
| 994 | (eq char-after-ip ?:)) | ||
| 995 | ;; this line should be indented relative to the beginning | ||
| 996 | ;; of indentation for the topmost-intro line that contains | ||
| 997 | ;; the prototype's open paren | ||
| 998 | ;; TBD: is the following redundant? | ||
| 999 | (if (eq char-before-ip ?:) | ||
| 1000 | (forward-char -1)) | ||
| 1001 | (c-backward-syntactic-ws lim) | ||
| 1002 | ;; TBD: is the preceding redundant? | ||
| 1003 | (if (eq (char-before) ?:) | ||
| 1004 | (progn (forward-char -1) | ||
| 1005 | (c-backward-syntactic-ws lim))) | ||
| 1006 | (if (eq (char-before) ?\)) | ||
| 1007 | (backward-sexp 1)) | ||
| 1008 | (setq placeholder (point)) | ||
| 1009 | (save-excursion | ||
| 1010 | (and (c-safe (backward-sexp 1) t) | ||
| 1011 | (looking-at "throw[^_]") | ||
| 1012 | (c-safe (backward-sexp 1) t) | ||
| 1013 | (setq placeholder (point)))) | ||
| 1014 | (goto-char placeholder) | ||
| 1015 | (c-add-syntax 'member-init-intro (c-point 'boi)) | ||
| 1016 | ;; we don't need to add any class offset since this | ||
| 1017 | ;; should be relative to the ctor's indentation | ||
| 1018 | ) | ||
| 1019 | ;; CASE 5B.2: K&R arg decl intro | ||
| 1020 | (c-recognize-knr-p | ||
| 1021 | (c-add-syntax 'knr-argdecl-intro (c-point 'boi)) | ||
| 1022 | (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0)))) | ||
| 1023 | ;; CASE 5B.3: Nether region after a C++ or Java func | ||
| 1024 | ;; decl, which could include a `throws' declaration. | ||
| 1025 | (t | ||
| 1026 | (c-beginning-of-statement-1 lim) | ||
| 1027 | (c-add-syntax 'func-decl-cont (c-point 'boi)) | ||
| 1028 | ))) | ||
| 1029 | ;; CASE 5C: inheritance line. could be first inheritance | ||
| 1030 | ;; line, or continuation of a multiple inheritance | ||
| 1031 | ((or (and c-baseclass-key (looking-at c-baseclass-key)) | ||
| 1032 | (and (or (eq char-before-ip ?:) | ||
| 1033 | ;; watch out for scope operator | ||
| 1034 | (save-excursion | ||
| 1035 | (and (eq char-after-ip ?:) | ||
| 1036 | (c-safe (progn (forward-char 1) t)) | ||
| 1037 | (not (eq (char-after) ?:)) | ||
| 1038 | ))) | ||
| 1039 | (save-excursion | ||
| 1040 | (c-backward-syntactic-ws lim) | ||
| 1041 | (if (eq char-before-ip ?:) | ||
| 1042 | (progn | ||
| 1043 | (forward-char -1) | ||
| 1044 | (c-backward-syntactic-ws lim))) | ||
| 1045 | (back-to-indentation) | ||
| 1046 | (looking-at c-class-key))) | ||
| 1047 | ;; for Java | ||
| 1048 | (and (eq major-mode 'java-mode) | ||
| 1049 | (let ((fence (save-excursion | ||
| 1050 | (c-beginning-of-statement-1 lim) | ||
| 1051 | (point))) | ||
| 1052 | cont done) | ||
| 1053 | (save-excursion | ||
| 1054 | (while (not done) | ||
| 1055 | (cond ((looking-at c-Java-special-key) | ||
| 1056 | (setq injava-inher (cons cont (point)) | ||
| 1057 | done t)) | ||
| 1058 | ((or (not (c-safe (forward-sexp -1) t)) | ||
| 1059 | (<= (point) fence)) | ||
| 1060 | (setq done t)) | ||
| 1061 | ) | ||
| 1062 | (setq cont t))) | ||
| 1063 | injava-inher) | ||
| 1064 | (not (c-crosses-statement-barrier-p (cdr injava-inher) | ||
| 1065 | (point))) | ||
| 1066 | )) | ||
| 1067 | (cond | ||
| 1068 | ;; CASE 5C.1: non-hanging colon on an inher intro | ||
| 1069 | ((eq char-after-ip ?:) | ||
| 1070 | (c-backward-syntactic-ws lim) | ||
| 1071 | (c-add-syntax 'inher-intro (c-point 'boi)) | ||
| 1072 | ;; don't add inclass symbol since relative point already | ||
| 1073 | ;; contains any class offset | ||
| 1074 | ) | ||
| 1075 | ;; CASE 5C.2: hanging colon on an inher intro | ||
| 1076 | ((eq char-before-ip ?:) | ||
| 1077 | (c-add-syntax 'inher-intro (c-point 'boi)) | ||
| 1078 | (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0)))) | ||
| 1079 | ;; CASE 5C.3: in a Java implements/extends | ||
| 1080 | (injava-inher | ||
| 1081 | (let ((where (cdr injava-inher)) | ||
| 1082 | (cont (car injava-inher))) | ||
| 1083 | (goto-char where) | ||
| 1084 | (cond ((looking-at "throws[ \t\n]") | ||
| 1085 | (c-add-syntax 'func-decl-cont | ||
| 1086 | (progn (c-beginning-of-statement-1 lim) | ||
| 1087 | (c-point 'boi)))) | ||
| 1088 | (cont (c-add-syntax 'inher-cont where)) | ||
| 1089 | (t (c-add-syntax 'inher-intro | ||
| 1090 | (progn (goto-char (cdr injava-inher)) | ||
| 1091 | (c-beginning-of-statement-1 lim) | ||
| 1092 | (point)))) | ||
| 1093 | ))) | ||
| 1094 | ;; CASE 5C.4: a continued inheritance line | ||
| 1095 | (t | ||
| 1096 | (c-beginning-of-inheritance-list lim) | ||
| 1097 | (c-add-syntax 'inher-cont (point)) | ||
| 1098 | ;; don't add inclass symbol since relative point already | ||
| 1099 | ;; contains any class offset | ||
| 1100 | ))) | ||
| 1101 | ;; CASE 5D: this could be a top-level compound statement or a | ||
| 1102 | ;; member init list continuation | ||
| 1103 | ((eq char-before-ip ?,) | ||
| 1104 | (goto-char indent-point) | ||
| 1105 | (c-backward-syntactic-ws lim) | ||
| 1106 | (while (and (< lim (point)) | ||
| 1107 | (eq (char-before) ?,)) | ||
| 1108 | ;; this will catch member inits with multiple | ||
| 1109 | ;; line arglists | ||
| 1110 | (forward-char -1) | ||
| 1111 | (c-backward-syntactic-ws (c-point 'bol)) | ||
| 1112 | (if (eq (char-before) ?\)) | ||
| 1113 | (backward-sexp 1)) | ||
| 1114 | ;; now continue checking | ||
| 1115 | (beginning-of-line) | ||
| 1116 | (c-backward-syntactic-ws lim)) | ||
| 1117 | (cond | ||
| 1118 | ;; CASE 5D.1: hanging member init colon, but watch out | ||
| 1119 | ;; for bogus matches on access specifiers inside classes. | ||
| 1120 | ((and (eq (char-before) ?:) | ||
| 1121 | (save-excursion | ||
| 1122 | (forward-word -1) | ||
| 1123 | (not (looking-at c-access-key)))) | ||
| 1124 | (goto-char indent-point) | ||
| 1125 | (c-backward-syntactic-ws lim) | ||
| 1126 | (c-safe (backward-sexp 1)) | ||
| 1127 | (c-add-syntax 'member-init-cont (c-point 'boi)) | ||
| 1128 | ;; we do not need to add class offset since relative | ||
| 1129 | ;; point is the member init above us | ||
| 1130 | ) | ||
| 1131 | ;; CASE 5D.2: non-hanging member init colon | ||
| 1132 | ((progn | ||
| 1133 | (c-forward-syntactic-ws indent-point) | ||
| 1134 | (eq (char-after) ?:)) | ||
| 1135 | (skip-chars-forward " \t:") | ||
| 1136 | (c-add-syntax 'member-init-cont (point))) | ||
| 1137 | ;; CASE 5D.3: perhaps a multiple inheritance line? | ||
| 1138 | ((looking-at c-inher-key) | ||
| 1139 | (c-add-syntax 'inher-cont (c-point 'boi))) | ||
| 1140 | ;; CASE 5D.4: perhaps a template list continuation? | ||
| 1141 | ((save-excursion | ||
| 1142 | (skip-chars-backward "^<" lim) | ||
| 1143 | ;; not sure if this is the right test, but it should | ||
| 1144 | ;; be fast and mostly accurate. | ||
| 1145 | (and (eq (char-before) ?<) | ||
| 1146 | (not (c-in-literal lim)))) | ||
| 1147 | ;; we can probably indent it just like and arglist-cont | ||
| 1148 | (c-add-syntax 'arglist-cont (point))) | ||
| 1149 | ;; CASE 5D.5: perhaps a top-level statement-cont | ||
| 1150 | (t | ||
| 1151 | (c-beginning-of-statement-1 lim) | ||
| 1152 | ;; skip over any access-specifiers | ||
| 1153 | (and inclass-p c-access-key | ||
| 1154 | (while (looking-at c-access-key) | ||
| 1155 | (forward-line 1))) | ||
| 1156 | ;; skip over comments, whitespace | ||
| 1157 | (c-forward-syntactic-ws indent-point) | ||
| 1158 | (c-add-syntax 'statement-cont (c-point 'boi))) | ||
| 1159 | )) | ||
| 1160 | ;; CASE 5E: we are looking at a access specifier | ||
| 1161 | ((and inclass-p | ||
| 1162 | c-access-key | ||
| 1163 | (looking-at c-access-key)) | ||
| 1164 | (c-add-syntax 'access-label (c-point 'bonl)) | ||
| 1165 | (c-add-syntax 'inclass (aref inclass-p 0))) | ||
| 1166 | ;; CASE 5F: extern-lang-close? | ||
| 1167 | ((and inextern-p | ||
| 1168 | (eq char-after-ip ?})) | ||
| 1169 | (c-add-syntax 'extern-lang-close (aref inclass-p 1))) | ||
| 1170 | ;; CASE 5G: we are looking at the brace which closes the | ||
| 1171 | ;; enclosing nested class decl | ||
| 1172 | ((and inclass-p | ||
| 1173 | (eq char-after-ip ?}) | ||
| 1174 | (save-excursion | ||
| 1175 | (save-restriction | ||
| 1176 | (widen) | ||
| 1177 | (forward-char 1) | ||
| 1178 | (and | ||
| 1179 | (condition-case nil | ||
| 1180 | (progn (backward-sexp 1) t) | ||
| 1181 | (error nil)) | ||
| 1182 | (= (point) (aref inclass-p 1)) | ||
| 1183 | )))) | ||
| 1184 | (save-restriction | ||
| 1185 | (widen) | ||
| 1186 | (goto-char (aref inclass-p 0)) | ||
| 1187 | (c-add-syntax 'class-close (c-point 'boi)))) | ||
| 1188 | ;; CASE 5H: we could be looking at subsequent knr-argdecls | ||
| 1189 | ((and c-recognize-knr-p | ||
| 1190 | ;; here we essentially use the hack that is used in | ||
| 1191 | ;; Emacs' c-mode.el to limit how far back we should | ||
| 1192 | ;; look. The assumption is made that argdecls are | ||
| 1193 | ;; indented at least one space and that function | ||
| 1194 | ;; headers are not indented. | ||
| 1195 | (let ((limit (save-excursion | ||
| 1196 | (re-search-backward "^[^ \^L\t\n#]" nil 'move) | ||
| 1197 | (point)))) | ||
| 1198 | (save-excursion | ||
| 1199 | (c-backward-syntactic-ws limit) | ||
| 1200 | (setq placeholder (point)) | ||
| 1201 | (while (and (memq (char-before) '(?\; ?,)) | ||
| 1202 | (> (point) limit)) | ||
| 1203 | (beginning-of-line) | ||
| 1204 | (setq placeholder (point)) | ||
| 1205 | (c-backward-syntactic-ws limit)) | ||
| 1206 | (and (eq (char-before) ?\)) | ||
| 1207 | (or (not c-method-key) | ||
| 1208 | (progn | ||
| 1209 | (forward-sexp -1) | ||
| 1210 | (forward-char -1) | ||
| 1211 | (c-backward-syntactic-ws) | ||
| 1212 | (not (or (memq (char-before) '(?- ?+)) | ||
| 1213 | ;; or a class category | ||
| 1214 | (progn | ||
| 1215 | (forward-sexp -2) | ||
| 1216 | (looking-at c-class-key)) | ||
| 1217 | ))))) | ||
| 1218 | )) | ||
| 1219 | (save-excursion | ||
| 1220 | (c-beginning-of-statement-1) | ||
| 1221 | (not (looking-at "typedef[ \t\n]+")))) | ||
| 1222 | (goto-char placeholder) | ||
| 1223 | (c-add-syntax 'knr-argdecl (c-point 'boi))) | ||
| 1224 | ;; CASE 5I: we are at the topmost level, make sure we skip | ||
| 1225 | ;; back past any access specifiers | ||
| 1226 | ((progn | ||
| 1227 | (c-backward-syntactic-ws lim) | ||
| 1228 | (while (and inclass-p | ||
| 1229 | c-access-key | ||
| 1230 | (not (bobp)) | ||
| 1231 | (save-excursion | ||
| 1232 | (c-safe (progn (backward-sexp 1) t)) | ||
| 1233 | (looking-at c-access-key))) | ||
| 1234 | (backward-sexp 1) | ||
| 1235 | (c-backward-syntactic-ws lim)) | ||
| 1236 | (or (bobp) | ||
| 1237 | (memq (char-before) '(?\; ?\})))) | ||
| 1238 | ;; real beginning-of-line could be narrowed out due to | ||
| 1239 | ;; enclosure in a class block | ||
| 1240 | (save-restriction | ||
| 1241 | (widen) | ||
| 1242 | (c-add-syntax 'topmost-intro (c-point 'bol)) | ||
| 1243 | (if inclass-p | ||
| 1244 | (progn | ||
| 1245 | (goto-char (aref inclass-p 1)) | ||
| 1246 | (if inextern-p | ||
| 1247 | (c-add-syntax 'inextern-lang) | ||
| 1248 | (c-add-syntax 'inclass (c-point 'boi))))) | ||
| 1249 | )) | ||
| 1250 | ;; CASE 5J: we are at an ObjC or Java method definition | ||
| 1251 | ;; continuation line. | ||
| 1252 | ((and c-method-key | ||
| 1253 | (progn | ||
| 1254 | (c-beginning-of-statement-1 lim) | ||
| 1255 | (beginning-of-line) | ||
| 1256 | (looking-at c-method-key))) | ||
| 1257 | (c-add-syntax 'objc-method-args-cont (point))) | ||
| 1258 | ;; CASE 5K: we are at a topmost continuation line | ||
| 1259 | (t | ||
| 1260 | (c-beginning-of-statement-1 lim) | ||
| 1261 | (c-forward-syntactic-ws) | ||
| 1262 | (c-add-syntax 'topmost-intro-cont (c-point 'boi))) | ||
| 1263 | )) ; end CASE 5 | ||
| 1264 | ;; CASE 6: line is an expression, not a statement. Most | ||
| 1265 | ;; likely we are either in a function prototype or a function | ||
| 1266 | ;; call argument list | ||
| 1267 | ((not (eq (char-after containing-sexp) ?{)) | ||
| 1268 | (c-backward-syntactic-ws containing-sexp) | ||
| 1269 | (cond | ||
| 1270 | ;; CASE 6A: we are looking at the arglist closing paren | ||
| 1271 | ((and (not (eq char-before-ip ?,)) | ||
| 1272 | (memq char-after-ip '(?\) ?\]))) | ||
| 1273 | (goto-char containing-sexp) | ||
| 1274 | (c-add-syntax 'arglist-close (c-point 'boi))) | ||
| 1275 | ;; CASE 6B: we are looking at the first argument in an empty | ||
| 1276 | ;; argument list. Use arglist-close if we're actually | ||
| 1277 | ;; looking at a close paren or bracket. | ||
| 1278 | ((memq char-before-ip '(?\( ?\[)) | ||
| 1279 | (goto-char containing-sexp) | ||
| 1280 | (c-add-syntax 'arglist-intro (c-point 'boi))) | ||
| 1281 | ;; CASE 6C: we are inside a conditional test clause. treat | ||
| 1282 | ;; these things as statements | ||
| 1283 | ((save-excursion | ||
| 1284 | (goto-char containing-sexp) | ||
| 1285 | (and (c-safe (progn (forward-sexp -1) t)) | ||
| 1286 | (looking-at "\\<for\\>[^_]"))) | ||
| 1287 | (goto-char (1+ containing-sexp)) | ||
| 1288 | (c-forward-syntactic-ws indent-point) | ||
| 1289 | (c-beginning-of-statement-1 containing-sexp) | ||
| 1290 | (if (eq char-before-ip ?\;) | ||
| 1291 | (c-add-syntax 'statement (point)) | ||
| 1292 | (c-add-syntax 'statement-cont (point)) | ||
| 1293 | )) | ||
| 1294 | ;; CASE 6D: maybe a continued method call. This is the case | ||
| 1295 | ;; when we are inside a [] bracketed exp, and what precede | ||
| 1296 | ;; the opening bracket is not an identifier. | ||
| 1297 | ((and c-method-key | ||
| 1298 | (eq (char-after containing-sexp) ?\[) | ||
| 1299 | (save-excursion | ||
| 1300 | (goto-char (1- containing-sexp)) | ||
| 1301 | (c-backward-syntactic-ws (c-point 'bod)) | ||
| 1302 | (if (not (looking-at c-symbol-key)) | ||
| 1303 | (c-add-syntax 'objc-method-call-cont containing-sexp)) | ||
| 1304 | ))) | ||
| 1305 | ;; CASE 6E: we are looking at an arglist continuation line, | ||
| 1306 | ;; but the preceding argument is on the same line as the | ||
| 1307 | ;; opening paren. This case includes multi-line | ||
| 1308 | ;; mathematical paren groupings, but we could be on a | ||
| 1309 | ;; for-list continuation line | ||
| 1310 | ((and (save-excursion | ||
| 1311 | (goto-char (1+ containing-sexp)) | ||
| 1312 | (skip-chars-forward " \t") | ||
| 1313 | (not (eolp))) | ||
| 1314 | (save-excursion | ||
| 1315 | (c-beginning-of-statement-1 lim) | ||
| 1316 | (skip-chars-backward " \t([") | ||
| 1317 | (<= (point) containing-sexp))) | ||
| 1318 | (goto-char containing-sexp) | ||
| 1319 | (c-add-syntax 'arglist-cont-nonempty (c-point 'boi))) | ||
| 1320 | ;; CASE 6F: we are looking at just a normal arglist | ||
| 1321 | ;; continuation line | ||
| 1322 | (t (c-beginning-of-statement-1 containing-sexp) | ||
| 1323 | (forward-char 1) | ||
| 1324 | (c-forward-syntactic-ws indent-point) | ||
| 1325 | (c-add-syntax 'arglist-cont (c-point 'boi))) | ||
| 1326 | )) | ||
| 1327 | ;; CASE 7: func-local multi-inheritance line | ||
| 1328 | ((and c-baseclass-key | ||
| 1329 | (save-excursion | ||
| 1330 | (goto-char indent-point) | ||
| 1331 | (skip-chars-forward " \t") | ||
| 1332 | (looking-at c-baseclass-key))) | ||
| 1333 | (goto-char indent-point) | ||
| 1334 | (skip-chars-forward " \t") | ||
| 1335 | (cond | ||
| 1336 | ;; CASE 7A: non-hanging colon on an inher intro | ||
| 1337 | ((eq char-after-ip ?:) | ||
| 1338 | (c-backward-syntactic-ws lim) | ||
| 1339 | (c-add-syntax 'inher-intro (c-point 'boi))) | ||
| 1340 | ;; CASE 7B: hanging colon on an inher intro | ||
| 1341 | ((eq char-before-ip ?:) | ||
| 1342 | (c-add-syntax 'inher-intro (c-point 'boi))) | ||
| 1343 | ;; CASE 7C: a continued inheritance line | ||
| 1344 | (t | ||
| 1345 | (c-beginning-of-inheritance-list lim) | ||
| 1346 | (c-add-syntax 'inher-cont (point)) | ||
| 1347 | ))) | ||
| 1348 | ;; CASE 8: we are inside a brace-list | ||
| 1349 | ((setq placeholder (c-inside-bracelist-p containing-sexp state)) | ||
| 1350 | (cond | ||
| 1351 | ;; CASE 8A: brace-list-close brace | ||
| 1352 | ((and (eq char-after-ip ?}) | ||
| 1353 | (c-safe (progn (forward-char 1) | ||
| 1354 | (backward-sexp 1) | ||
| 1355 | t)) | ||
| 1356 | (= (point) containing-sexp)) | ||
| 1357 | (c-add-syntax 'brace-list-close (c-point 'boi))) | ||
| 1358 | ;; CASE 8B: we're looking at the first line in a brace-list | ||
| 1359 | ((save-excursion | ||
| 1360 | (goto-char indent-point) | ||
| 1361 | (c-backward-syntactic-ws containing-sexp) | ||
| 1362 | (= (point) (1+ containing-sexp))) | ||
| 1363 | (goto-char containing-sexp) | ||
| 1364 | (c-add-syntax 'brace-list-intro (c-point 'boi)) | ||
| 1365 | ) | ||
| 1366 | ;;)) ; end CASE 8B | ||
| 1367 | ;; CASE 8C: this is just a later brace-list-entry | ||
| 1368 | (t (goto-char (1+ containing-sexp)) | ||
| 1369 | (c-forward-syntactic-ws indent-point) | ||
| 1370 | (if (eq char-after-ip ?{) | ||
| 1371 | (c-add-syntax 'brace-list-open (point)) | ||
| 1372 | (c-add-syntax 'brace-list-entry (point)) | ||
| 1373 | )) ; end CASE 8C | ||
| 1374 | )) ; end CASE 8 | ||
| 1375 | ;; CASE 9: A continued statement | ||
| 1376 | ((and (not (memq char-before-ip '(?\; ?} ?:))) | ||
| 1377 | (> (point) | ||
| 1378 | (save-excursion | ||
| 1379 | (c-beginning-of-statement-1 containing-sexp) | ||
| 1380 | (setq placeholder (point)))) | ||
| 1381 | (/= placeholder containing-sexp)) | ||
| 1382 | (goto-char indent-point) | ||
| 1383 | (skip-chars-forward " \t") | ||
| 1384 | (let ((after-cond-placeholder | ||
| 1385 | (save-excursion | ||
| 1386 | (goto-char placeholder) | ||
| 1387 | (if (looking-at c-conditional-key) | ||
| 1388 | (progn | ||
| 1389 | (c-safe (c-skip-conditional)) | ||
| 1390 | (c-forward-syntactic-ws) | ||
| 1391 | (if (eq (char-after) ?\;) | ||
| 1392 | (progn | ||
| 1393 | (forward-char 1) | ||
| 1394 | (c-forward-syntactic-ws))) | ||
| 1395 | (point)) | ||
| 1396 | nil)))) | ||
| 1397 | (cond | ||
| 1398 | ;; CASE 9A: substatement | ||
| 1399 | ((and after-cond-placeholder | ||
| 1400 | (>= after-cond-placeholder indent-point)) | ||
| 1401 | (goto-char placeholder) | ||
| 1402 | (if (eq char-after-ip ?{) | ||
| 1403 | (c-add-syntax 'substatement-open (c-point 'boi)) | ||
| 1404 | (c-add-syntax 'substatement (c-point 'boi)))) | ||
| 1405 | ;; CASE 9B: open braces for class or brace-lists | ||
| 1406 | ((eq char-after-ip ?{) | ||
| 1407 | (cond | ||
| 1408 | ;; CASE 9B.1: class-open | ||
| 1409 | ((save-excursion | ||
| 1410 | (goto-char indent-point) | ||
| 1411 | (skip-chars-forward " \t{") | ||
| 1412 | (let ((decl (c-search-uplist-for-classkey (c-parse-state)))) | ||
| 1413 | (and decl | ||
| 1414 | (setq placeholder (aref decl 0))) | ||
| 1415 | )) | ||
| 1416 | (c-add-syntax 'class-open placeholder)) | ||
| 1417 | ;; CASE 9B.2: brace-list-open | ||
| 1418 | ((or (save-excursion | ||
| 1419 | (goto-char placeholder) | ||
| 1420 | (looking-at "\\<enum\\>")) | ||
| 1421 | (eq char-before-ip ?=)) | ||
| 1422 | (c-add-syntax 'brace-list-open placeholder)) | ||
| 1423 | ;; CASE 9B.3: catch-all for unknown construct. | ||
| 1424 | (t | ||
| 1425 | ;; Can and should I add an extensibility hook here? | ||
| 1426 | ;; Something like c-recognize-hook so support for | ||
| 1427 | ;; unknown constructs could be added. It's probably a | ||
| 1428 | ;; losing proposition, so I dunno. | ||
| 1429 | (goto-char placeholder) | ||
| 1430 | (c-add-syntax 'statement-cont (c-point 'boi)) | ||
| 1431 | (c-add-syntax 'block-open)) | ||
| 1432 | )) | ||
| 1433 | ;; CASE 9C: iostream insertion or extraction operator | ||
| 1434 | ((looking-at "<<\\|>>") | ||
| 1435 | (goto-char placeholder) | ||
| 1436 | (and after-cond-placeholder | ||
| 1437 | (goto-char after-cond-placeholder)) | ||
| 1438 | (while (and (re-search-forward "<<\\|>>" indent-point 'move) | ||
| 1439 | (c-in-literal placeholder))) | ||
| 1440 | ;; if we ended up at indent-point, then the first | ||
| 1441 | ;; streamop is on a separate line. Indent the line like | ||
| 1442 | ;; a statement-cont instead | ||
| 1443 | (if (/= (point) indent-point) | ||
| 1444 | (c-add-syntax 'stream-op (c-point 'boi)) | ||
| 1445 | (c-backward-syntactic-ws lim) | ||
| 1446 | (c-add-syntax 'statement-cont (c-point 'boi)))) | ||
| 1447 | ;; CASE 9D: continued statement. find the accurate | ||
| 1448 | ;; beginning of statement or substatement | ||
| 1449 | (t | ||
| 1450 | (c-beginning-of-statement-1 after-cond-placeholder) | ||
| 1451 | ;; KLUDGE ALERT! c-beginning-of-statement-1 can leave | ||
| 1452 | ;; us before the lim we're passing in. It should be | ||
| 1453 | ;; fixed, but I'm worried about side-effects at this | ||
| 1454 | ;; late date. Fix for v5. | ||
| 1455 | (goto-char (or (and after-cond-placeholder | ||
| 1456 | (max after-cond-placeholder (point))) | ||
| 1457 | (point))) | ||
| 1458 | (c-add-syntax 'statement-cont (point))) | ||
| 1459 | ))) | ||
| 1460 | ;; CASE 10: an else clause? | ||
| 1461 | ((looking-at "\\<else\\>[^_]") | ||
| 1462 | (c-backward-to-start-of-if containing-sexp) | ||
| 1463 | (c-add-syntax 'else-clause (c-point 'boi))) | ||
| 1464 | ;; CASE 11: Statement. But what kind? Lets see if its a | ||
| 1465 | ;; while closure of a do/while construct | ||
| 1466 | ((progn | ||
| 1467 | (goto-char indent-point) | ||
| 1468 | (skip-chars-forward " \t") | ||
| 1469 | (and (looking-at "while\\b[^_]") | ||
| 1470 | (save-excursion | ||
| 1471 | (c-backward-to-start-of-do containing-sexp) | ||
| 1472 | (setq placeholder (point)) | ||
| 1473 | (looking-at "do\\b[^_]")) | ||
| 1474 | )) | ||
| 1475 | (c-add-syntax 'do-while-closure placeholder)) | ||
| 1476 | ;; CASE 12: A case or default label | ||
| 1477 | ((looking-at c-switch-label-key) | ||
| 1478 | (goto-char containing-sexp) | ||
| 1479 | ;; check for hanging braces | ||
| 1480 | (if (/= (point) (c-point 'boi)) | ||
| 1481 | (forward-sexp -1)) | ||
| 1482 | (c-add-syntax 'case-label (c-point 'boi))) | ||
| 1483 | ;; CASE 13: any other label | ||
| 1484 | ((looking-at c-label-key) | ||
| 1485 | (goto-char containing-sexp) | ||
| 1486 | (c-add-syntax 'label (c-point 'boi))) | ||
| 1487 | ;; CASE 14: block close brace, possibly closing the defun or | ||
| 1488 | ;; the class | ||
| 1489 | ((eq char-after-ip ?}) | ||
| 1490 | (let* ((lim (c-safe-position containing-sexp fullstate)) | ||
| 1491 | (relpos (save-excursion | ||
| 1492 | (goto-char containing-sexp) | ||
| 1493 | (if (/= (point) (c-point 'boi)) | ||
| 1494 | (c-beginning-of-statement-1 lim)) | ||
| 1495 | (c-point 'boi)))) | ||
| 1496 | (cond | ||
| 1497 | ;; CASE 14A: does this close an inline? | ||
| 1498 | ((let ((inclass-p (progn | ||
| 1499 | (goto-char containing-sexp) | ||
| 1500 | (c-search-uplist-for-classkey state)))) | ||
| 1501 | ;; inextern-p in higher level let* | ||
| 1502 | (setq inextern-p (and inclass-p | ||
| 1503 | (progn | ||
| 1504 | (goto-char (aref inclass-p 0)) | ||
| 1505 | (looking-at "extern[^_]")))) | ||
| 1506 | (and inclass-p (not inextern-p))) | ||
| 1507 | (c-add-syntax 'inline-close relpos)) | ||
| 1508 | ;; CASE 14B: if there an enclosing brace that hasn't | ||
| 1509 | ;; been narrowed out by a class, then this is a | ||
| 1510 | ;; block-close | ||
| 1511 | ((and (not inextern-p) | ||
| 1512 | (c-most-enclosing-brace state)) | ||
| 1513 | (c-add-syntax 'block-close relpos)) | ||
| 1514 | ;; CASE 14C: find out whether we're closing a top-level | ||
| 1515 | ;; class or a defun | ||
| 1516 | (t | ||
| 1517 | (save-restriction | ||
| 1518 | (narrow-to-region (point-min) indent-point) | ||
| 1519 | (let ((decl (c-search-uplist-for-classkey (c-parse-state)))) | ||
| 1520 | (if decl | ||
| 1521 | (c-add-syntax 'class-close (aref decl 0)) | ||
| 1522 | (c-add-syntax 'defun-close relpos))))) | ||
| 1523 | ))) | ||
| 1524 | ;; CASE 15: statement catchall | ||
| 1525 | (t | ||
| 1526 | ;; we know its a statement, but we need to find out if it is | ||
| 1527 | ;; the first statement in a block | ||
| 1528 | (goto-char containing-sexp) | ||
| 1529 | (forward-char 1) | ||
| 1530 | (c-forward-syntactic-ws indent-point) | ||
| 1531 | ;; now skip forward past any case/default clauses we might find. | ||
| 1532 | (while (or (c-skip-case-statement-forward fullstate indent-point) | ||
| 1533 | (and (looking-at c-switch-label-key) | ||
| 1534 | (not inswitch-p))) | ||
| 1535 | (setq inswitch-p t)) | ||
| 1536 | ;; we want to ignore non-case labels when skipping forward | ||
| 1537 | (while (and (looking-at c-label-key) | ||
| 1538 | (goto-char (match-end 0))) | ||
| 1539 | (c-forward-syntactic-ws indent-point)) | ||
| 1540 | (cond | ||
| 1541 | ;; CASE 15A: we are inside a case/default clause inside a | ||
| 1542 | ;; switch statement. find out if we are at the statement | ||
| 1543 | ;; just after the case/default label. | ||
| 1544 | ((and inswitch-p | ||
| 1545 | (progn | ||
| 1546 | (goto-char indent-point) | ||
| 1547 | (c-backward-syntactic-ws containing-sexp) | ||
| 1548 | (back-to-indentation) | ||
| 1549 | (setq placeholder (point)) | ||
| 1550 | (looking-at c-switch-label-key))) | ||
| 1551 | (goto-char indent-point) | ||
| 1552 | (skip-chars-forward " \t") | ||
| 1553 | (if (eq (char-after) ?{) | ||
| 1554 | (c-add-syntax 'statement-case-open placeholder) | ||
| 1555 | (c-add-syntax 'statement-case-intro placeholder))) | ||
| 1556 | ;; CASE 15B: continued statement | ||
| 1557 | ((eq char-before-ip ?,) | ||
| 1558 | (c-add-syntax 'statement-cont (c-point 'boi))) | ||
| 1559 | ;; CASE 15C: a question/colon construct? But make sure | ||
| 1560 | ;; what came before was not a label, and what comes after | ||
| 1561 | ;; is not a globally scoped function call! | ||
| 1562 | ((or (and (memq char-before-ip '(?: ??)) | ||
| 1563 | (save-excursion | ||
| 1564 | (goto-char indent-point) | ||
| 1565 | (c-backward-syntactic-ws lim) | ||
| 1566 | (back-to-indentation) | ||
| 1567 | (not (looking-at c-label-key)))) | ||
| 1568 | (and (memq char-after-ip '(?: ??)) | ||
| 1569 | (save-excursion | ||
| 1570 | (goto-char indent-point) | ||
| 1571 | (skip-chars-forward " \t") | ||
| 1572 | ;; watch out for scope operator | ||
| 1573 | (not (looking-at "::"))))) | ||
| 1574 | (c-add-syntax 'statement-cont (c-point 'boi))) | ||
| 1575 | ;; CASE 15D: any old statement | ||
| 1576 | ((< (point) indent-point) | ||
| 1577 | (let ((safepos (c-most-enclosing-brace fullstate)) | ||
| 1578 | relpos done) | ||
| 1579 | (goto-char indent-point) | ||
| 1580 | (c-beginning-of-statement-1 safepos) | ||
| 1581 | ;; It is possible we're on the brace that opens a nested | ||
| 1582 | ;; function. | ||
| 1583 | (if (and (eq (char-after) ?{) | ||
| 1584 | (save-excursion | ||
| 1585 | (c-backward-syntactic-ws safepos) | ||
| 1586 | (not (eq (char-before) ?\;)))) | ||
| 1587 | (c-beginning-of-statement-1 safepos)) | ||
| 1588 | (if (and inswitch-p | ||
| 1589 | (looking-at c-switch-label-key)) | ||
| 1590 | (progn | ||
| 1591 | (goto-char placeholder) | ||
| 1592 | (end-of-line) | ||
| 1593 | (forward-sexp -1))) | ||
| 1594 | (setq relpos (c-point 'boi)) | ||
| 1595 | (while (and (not done) | ||
| 1596 | (<= safepos (point)) | ||
| 1597 | (/= relpos (point))) | ||
| 1598 | (c-beginning-of-statement-1 safepos) | ||
| 1599 | (if (= relpos (c-point 'boi)) | ||
| 1600 | (setq done t)) | ||
| 1601 | (setq relpos (c-point 'boi))) | ||
| 1602 | (c-add-syntax 'statement relpos) | ||
| 1603 | (if (eq char-after-ip ?{) | ||
| 1604 | (c-add-syntax 'block-open)))) | ||
| 1605 | ;; CASE 15E: first statement in an inline, or first | ||
| 1606 | ;; statement in a top-level defun. we can tell this is it | ||
| 1607 | ;; if there are no enclosing braces that haven't been | ||
| 1608 | ;; narrowed out by a class (i.e. don't use bod here!) | ||
| 1609 | ((save-excursion | ||
| 1610 | (save-restriction | ||
| 1611 | (widen) | ||
| 1612 | (goto-char containing-sexp) | ||
| 1613 | (c-narrow-out-enclosing-class state containing-sexp) | ||
| 1614 | (not (c-most-enclosing-brace state)))) | ||
| 1615 | (goto-char containing-sexp) | ||
| 1616 | ;; if not at boi, then defun-opening braces are hung on | ||
| 1617 | ;; right side, so we need a different relpos | ||
| 1618 | (if (/= (point) (c-point 'boi)) | ||
| 1619 | (progn | ||
| 1620 | (c-backward-syntactic-ws) | ||
| 1621 | (c-safe (forward-sexp (if (eq (char-before) ?\)) | ||
| 1622 | -1 -2))) | ||
| 1623 | ;; looking at a Java throws clause following a | ||
| 1624 | ;; method's parameter list | ||
| 1625 | (c-beginning-of-statement-1) | ||
| 1626 | )) | ||
| 1627 | (c-add-syntax 'defun-block-intro (c-point 'boi))) | ||
| 1628 | ;; CASE 15F: first statement in a block | ||
| 1629 | (t (goto-char containing-sexp) | ||
| 1630 | (if (/= (point) (c-point 'boi)) | ||
| 1631 | (c-beginning-of-statement-1 | ||
| 1632 | (if (= (point) lim) | ||
| 1633 | (c-safe-position (point) state) lim))) | ||
| 1634 | (c-add-syntax 'statement-block-intro (c-point 'boi)) | ||
| 1635 | (if (eq char-after-ip ?{) | ||
| 1636 | (c-add-syntax 'block-open))) | ||
| 1637 | )) | ||
| 1638 | ) | ||
| 1639 | |||
| 1640 | ;; now we need to look at any modifiers | ||
| 1641 | (goto-char indent-point) | ||
| 1642 | (skip-chars-forward " \t") | ||
| 1643 | ;; are we looking at a comment only line? | ||
| 1644 | (if (looking-at c-comment-start-regexp) | ||
| 1645 | (c-add-syntax 'comment-intro)) | ||
| 1646 | ;; we might want to give additional offset to friends (in C++). | ||
| 1647 | (if (and (eq major-mode 'c++-mode) | ||
| 1648 | (looking-at c-C++-friend-key)) | ||
| 1649 | (c-add-syntax 'friend)) | ||
| 1650 | ;; return the syntax | ||
| 1651 | syntax)))) | ||
| 1652 | |||
| 1653 | |||
| 1654 | (defun c-echo-parsing-error () | ||
| 1655 | (if (not c-parsing-error) | ||
| 1656 | nil | ||
| 1657 | (message "unbalanced close brace at bufpos %d -- INDENTATION IS SUSPECT!" | ||
| 1658 | c-parsing-error) | ||
| 1659 | (ding)) | ||
| 1660 | c-parsing-error) | ||
| 1661 | |||
| 1662 | ;; indent via syntactic language elements | ||
| 1663 | (defun c-indent-line (&optional syntax) | ||
| 1664 | ;; indent the current line as C/C++/ObjC code. Optional SYNTAX is the | ||
| 1665 | ;; syntactic information for the current line. Returns the amount of | ||
| 1666 | ;; indentation change | ||
| 1667 | (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax))) | ||
| 1668 | (pos (- (point-max) (point))) | ||
| 1669 | (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context))) | ||
| 1670 | (shift-amt (- (current-indentation) indent))) | ||
| 1671 | (and c-echo-syntactic-information-p | ||
| 1672 | (not (c-echo-parsing-error)) | ||
| 1673 | (message "syntax: %s, indent= %d" c-syntactic-context indent)) | ||
| 1674 | (if (zerop shift-amt) | ||
| 1675 | nil | ||
| 1676 | (delete-region (c-point 'bol) (c-point 'boi)) | ||
| 1677 | (beginning-of-line) | ||
| 1678 | (indent-to indent)) | ||
| 1679 | (if (< (point) (c-point 'boi)) | ||
| 1680 | (back-to-indentation) | ||
| 1681 | ;; If initial point was within line's indentation, position after | ||
| 1682 | ;; the indentation. Else stay at same point in text. | ||
| 1683 | (if (> (- (point-max) pos) (point)) | ||
| 1684 | (goto-char (- (point-max) pos))) | ||
| 1685 | ) | ||
| 1686 | (run-hooks 'c-special-indent-hook) | ||
| 1687 | shift-amt)) | ||
| 1688 | |||
| 1689 | (defun c-show-syntactic-information (arg) | ||
| 1690 | "Show syntactic information for current line. | ||
| 1691 | With universal argument, inserts the analysis as a comment on that line." | ||
| 1692 | (interactive "P") | ||
| 1693 | (let ((syntax (c-guess-basic-syntax))) | ||
| 1694 | (if (not (consp arg)) | ||
| 1695 | (if (not (c-echo-parsing-error)) | ||
| 1696 | (message "syntactic analysis: %s" syntax)) | ||
| 1697 | (indent-for-comment) | ||
| 1698 | (insert (format "%s" syntax)) | ||
| 1699 | )) | ||
| 1700 | (c-keep-region-active)) | ||
| 1701 | |||
| 1702 | |||
| 1703 | (provide 'cc-engine) | ||
| 1704 | ;;; cc-engine.el ends here | ||
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el new file mode 100644 index 00000000000..03667e1870a --- /dev/null +++ b/lisp/progmodes/cc-langs.el | |||
| @@ -0,0 +1,551 @@ | |||
| 1 | ;;; cc-langs.el --- specific language support for 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.12 | ||
| 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 | ;; Regular expressions and other values which must be parameterized on | ||
| 32 | ;; a per-language basis. | ||
| 33 | |||
| 34 | ;; Keywords defining protection levels | ||
| 35 | (defconst c-protection-key "\\<\\(public\\|protected\\|private\\)\\>") | ||
| 36 | |||
| 37 | ;; Regex describing a `symbol' in all languages We cannot use just | ||
| 38 | ;; `word' syntax class since `_' cannot be in word class. Putting | ||
| 39 | ;; underscore in word class breaks forward word movement behavior that | ||
| 40 | ;; users are familiar with. | ||
| 41 | (defconst c-symbol-key "\\(\\w\\|\\s_\\)+") | ||
| 42 | |||
| 43 | |||
| 44 | ;; keywords introducing class definitions. language specific | ||
| 45 | (defconst c-C-class-key "\\(struct\\|union\\)") | ||
| 46 | (defconst c-C++-class-key "\\(class\\|struct\\|union\\)") | ||
| 47 | |||
| 48 | (defconst c-ObjC-class-key | ||
| 49 | (concat | ||
| 50 | "@\\(interface\\|implementation\\)\\s +" | ||
| 51 | c-symbol-key ;name of the class | ||
| 52 | "\\(\\s *:\\s *" c-symbol-key "\\)?" ;maybe followed by the superclass | ||
| 53 | "\\(\\s *<[^>]+>\\)?" ;and maybe the adopted protocols list | ||
| 54 | )) | ||
| 55 | |||
| 56 | (defconst c-Java-class-key | ||
| 57 | (concat | ||
| 58 | "\\(" c-protection-key "\\s +\\)?" | ||
| 59 | "\\(interface\\|class\\)\\s +" | ||
| 60 | c-symbol-key ;name of the class | ||
| 61 | "\\(\\s *extends\\s *" c-symbol-key "\\)?" ;maybe followed by superclass | ||
| 62 | ;;"\\(\\s *implements *[^{]+{\\)?" ;maybe the adopted protocols list | ||
| 63 | )) | ||
| 64 | |||
| 65 | (defvar c-class-key c-C-class-key) | ||
| 66 | (make-variable-buffer-local 'c-class-key) | ||
| 67 | |||
| 68 | |||
| 69 | ;; regexp describing access protection clauses. language specific | ||
| 70 | (defvar c-access-key nil) | ||
| 71 | (make-variable-buffer-local 'c-access-key) | ||
| 72 | (defconst c-C++-access-key (concat c-protection-key "[ \t]*:")) | ||
| 73 | (defconst c-ObjC-access-key (concat "@" c-protection-key)) | ||
| 74 | (defconst c-Java-access-key nil) | ||
| 75 | |||
| 76 | |||
| 77 | ;; keywords introducing conditional blocks | ||
| 78 | (defconst c-C-conditional-key nil) | ||
| 79 | (defconst c-C++-conditional-key nil) | ||
| 80 | (defconst c-Java-conditional-key nil) | ||
| 81 | |||
| 82 | (let ((all-kws "for\\|if\\|do\\|else\\|while\\|switch") | ||
| 83 | (exc-kws "\\|try\\|catch") | ||
| 84 | (thr-kws "\\|finally\\|synchronized") | ||
| 85 | (front "\\b\\(") | ||
| 86 | (back "\\)\\b[^_]")) | ||
| 87 | (setq c-C-conditional-key (concat front all-kws back) | ||
| 88 | c-C++-conditional-key (concat front all-kws exc-kws back) | ||
| 89 | c-Java-conditional-key (concat front all-kws exc-kws thr-kws back))) | ||
| 90 | |||
| 91 | (defvar c-conditional-key c-C-conditional-key) | ||
| 92 | (make-variable-buffer-local 'c-conditional-key) | ||
| 93 | |||
| 94 | |||
| 95 | ;; keywords describing method definition introductions | ||
| 96 | (defvar c-method-key nil) | ||
| 97 | (make-variable-buffer-local 'c-method-key) | ||
| 98 | |||
| 99 | (defconst c-ObjC-method-key | ||
| 100 | (concat | ||
| 101 | "^\\s *[+-]\\s *" | ||
| 102 | "\\(([^)]*)\\)?" ; return type | ||
| 103 | ;; \\s- in objc syntax table does not include \n | ||
| 104 | ;; since it is considered the end of //-comments. | ||
| 105 | "[ \t\n]*" c-symbol-key)) | ||
| 106 | |||
| 107 | (defconst c-Java-method-key | ||
| 108 | (concat | ||
| 109 | "^\\s *[+-]\\s *" | ||
| 110 | "\\(([^)]*)\\)?" ; return type | ||
| 111 | ;; \\s- in java syntax table does not include \n | ||
| 112 | ;; since it is considered the end of //-comments. | ||
| 113 | "[ \t\n]*" c-symbol-key)) | ||
| 114 | |||
| 115 | |||
| 116 | ;; comment starter definitions for various languages. language specific | ||
| 117 | (defconst c-C-comment-start-regexp "/[*]") | ||
| 118 | (defconst c-C++-comment-start-regexp "/[/*]") | ||
| 119 | ;; We need to match all 3 Java style comments | ||
| 120 | ;; 1) Traditional C block; 2) javadoc /** ...; 3) C++ style | ||
| 121 | (defconst c-Java-comment-start-regexp "/\\(/\\|[*][*]?\\)") | ||
| 122 | (defvar c-comment-start-regexp c-C-comment-start-regexp) | ||
| 123 | (make-variable-buffer-local 'c-comment-start-regexp) | ||
| 124 | |||
| 125 | |||
| 126 | |||
| 127 | ;; Regexp describing a switch's case or default label for all languages | ||
| 128 | (defconst c-switch-label-key "\\(\\(case[( \t]+\\S .*\\)\\|default[ \t]*\\):") | ||
| 129 | ;; Regexp describing any label. | ||
| 130 | (defconst c-label-key (concat c-symbol-key ":\\([^:]\\|$\\)")) | ||
| 131 | |||
| 132 | ;; Regexp describing class inheritance declarations. TBD: this should | ||
| 133 | ;; be language specific, and only makes sense for C++ | ||
| 134 | (defconst c-inher-key | ||
| 135 | (concat "\\(\\<static\\>\\s +\\)?" | ||
| 136 | c-C++-class-key "[ \t]+" c-symbol-key | ||
| 137 | "\\([ \t]*:[ \t]*\\)\\s *[^;]")) | ||
| 138 | |||
| 139 | ;; Regexp describing C++ base classes in a derived class definition. | ||
| 140 | ;; TBD: this should be language specific, and only makes sense for C++ | ||
| 141 | (defvar c-baseclass-key | ||
| 142 | (concat | ||
| 143 | ":?[ \t]*\\(virtual[ \t]+\\)?\\(" | ||
| 144 | c-protection-key "[ \t]+\\)" c-symbol-key)) | ||
| 145 | (make-variable-buffer-local 'c-baseclass-key) | ||
| 146 | |||
| 147 | ;; Regexp describing friend declarations in C++ classes. | ||
| 148 | (defconst c-C++-friend-key | ||
| 149 | "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+") | ||
| 150 | |||
| 151 | ;; Regexp describing Java inheritance and throws clauses. | ||
| 152 | (defconst c-Java-special-key "\\(implements\\|extends\\|throws\\)[^_]") | ||
| 153 | |||
| 154 | ;; Regexp describing the beginning of a Java top-level definition. | ||
| 155 | (defconst c-Java-defun-prompt-regexp | ||
| 156 | "^[ \t]*\\(\\(\\(public\\|protected\\|private\\|const\\|abstract\\|synchronized\\|final\\|static\\|threadsafe\\|transient\\|native\\|volatile\\)\\s-+\\)*\\(\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*[][_$.a-zA-Z0-9]+\\|[[a-zA-Z]\\)\\s-*\\)\\s-+\\)\\)?\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*\\s-+\\)\\s-*\\)?\\([_a-zA-Z][^][ \t:;.,{}()=]*\\|\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)\\)\\s-*\\(([^);{}]*)\\)?\\([] \t]*\\)\\(\\s-*\\<throws\\>\\s-*\\(\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)[, \t\n\r\f]*\\)+\\)?\\s-*") | ||
| 157 | |||
| 158 | |||
| 159 | |||
| 160 | ;; internal state variables | ||
| 161 | |||
| 162 | ;; Internal state of hungry delete key feature | ||
| 163 | (defvar c-hungry-delete-key nil) | ||
| 164 | (make-variable-buffer-local 'c-hungry-delete-key) | ||
| 165 | |||
| 166 | ;; Internal state of auto newline feature. | ||
| 167 | (defvar c-auto-newline nil) | ||
| 168 | (make-variable-buffer-local 'c-auto-newline) | ||
| 169 | |||
| 170 | ;; Internal auto-newline/hungry-delete designation string for mode line. | ||
| 171 | (defvar c-auto-hungry-string nil) | ||
| 172 | (make-variable-buffer-local 'c-auto-hungry-string) | ||
| 173 | |||
| 174 | ;; Buffer local language-specific comment style flag. | ||
| 175 | (defvar c-double-slash-is-comments-p nil) | ||
| 176 | (make-variable-buffer-local 'c-double-slash-is-comments-p) | ||
| 177 | |||
| 178 | ;; Non-nil means K&R style argument declarations are valid. | ||
| 179 | (defvar c-recognize-knr-p t) | ||
| 180 | (make-variable-buffer-local 'c-recognize-knr-p) | ||
| 181 | |||
| 182 | |||
| 183 | |||
| 184 | (defun c-use-java-style () | ||
| 185 | "Institutes `java' indentation style. | ||
| 186 | For use with the variable `java-mode-hook'." | ||
| 187 | (c-set-style "java")) | ||
| 188 | |||
| 189 | (defvar c-styles-are-initialized nil) | ||
| 190 | |||
| 191 | (defun c-common-init () | ||
| 192 | ;; Common initializations for all modes. | ||
| 193 | (if c-styles-are-initialized | ||
| 194 | nil | ||
| 195 | (require 'cc-styles) | ||
| 196 | (c-initialize-builtin-style) | ||
| 197 | (if c-style-variables-are-local-p | ||
| 198 | (c-make-styles-buffer-local)) | ||
| 199 | (setq c-styles-are-initialized t)) | ||
| 200 | ;; these variables should always be buffer local; they do not affect | ||
| 201 | ;; indentation style. | ||
| 202 | (make-local-variable 'paragraph-start) | ||
| 203 | (make-local-variable 'paragraph-separate) | ||
| 204 | (make-local-variable 'paragraph-ignore-fill-prefix) | ||
| 205 | (make-local-variable 'require-final-newline) | ||
| 206 | (make-local-variable 'parse-sexp-ignore-comments) | ||
| 207 | (make-local-variable 'indent-line-function) | ||
| 208 | (make-local-variable 'indent-region-function) | ||
| 209 | (make-local-variable 'comment-start) | ||
| 210 | (make-local-variable 'comment-end) | ||
| 211 | (make-local-variable 'comment-column) | ||
| 212 | (make-local-variable 'comment-start-skip) | ||
| 213 | (make-local-variable 'comment-multi-line) | ||
| 214 | (make-local-variable 'outline-regexp) | ||
| 215 | (make-local-variable 'outline-level) | ||
| 216 | (make-local-variable 'adaptive-fill-regexp) | ||
| 217 | (make-local-variable 'imenu-generic-expression) ;set in the mode functions | ||
| 218 | ;; Emacs 19.30 and beyond only, AFAIK | ||
| 219 | (if (boundp 'fill-paragraph-function) | ||
| 220 | (progn | ||
| 221 | (make-local-variable 'fill-paragraph-function) | ||
| 222 | (setq fill-paragraph-function 'c-fill-paragraph))) | ||
| 223 | ;; now set their values | ||
| 224 | (setq paragraph-start (concat page-delimiter "\\|$") | ||
| 225 | paragraph-separate paragraph-start | ||
| 226 | paragraph-ignore-fill-prefix t | ||
| 227 | require-final-newline t | ||
| 228 | parse-sexp-ignore-comments t | ||
| 229 | indent-line-function 'c-indent-line | ||
| 230 | indent-region-function 'c-indent-region | ||
| 231 | outline-regexp "[^#\n\^M]" | ||
| 232 | outline-level 'c-outline-level | ||
| 233 | comment-column 32 | ||
| 234 | comment-start-skip "/\\*+ *\\|// *" | ||
| 235 | adaptive-fill-regexp nil) | ||
| 236 | ;; we have to do something special for c-offsets-alist so that the | ||
| 237 | ;; buffer local value has its own alist structure. | ||
| 238 | (setq c-offsets-alist (copy-alist c-offsets-alist)) | ||
| 239 | ;; setup the comment indent variable in a Emacs version portable way | ||
| 240 | ;; ignore any byte compiler warnings you might get here | ||
| 241 | (make-local-variable 'comment-indent-function) | ||
| 242 | (setq comment-indent-function 'c-comment-indent) | ||
| 243 | ;; add menus to menubar | ||
| 244 | (easy-menu-add (c-mode-menu mode-name)) | ||
| 245 | ;; put auto-hungry designators onto minor-mode-alist, but only once | ||
| 246 | (or (assq 'c-auto-hungry-string minor-mode-alist) | ||
| 247 | (setq minor-mode-alist | ||
| 248 | (cons '(c-auto-hungry-string c-auto-hungry-string) | ||
| 249 | minor-mode-alist)))) | ||
| 250 | |||
| 251 | (defun c-postprocess-file-styles () | ||
| 252 | "Function that post processes relevant file local variables. | ||
| 253 | Currently, this function simply applies any style and offset settings | ||
| 254 | found in the file's Local Variable list. It first applies any style | ||
| 255 | setting found in `c-file-style', then it applies any offset settings | ||
| 256 | it finds in `c-file-offsets'." | ||
| 257 | ;; apply file styles and offsets | ||
| 258 | (and c-file-style | ||
| 259 | (c-set-style c-file-style)) | ||
| 260 | (and c-file-offsets | ||
| 261 | (mapcar | ||
| 262 | (function | ||
| 263 | (lambda (langentry) | ||
| 264 | (let ((langelem (car langentry)) | ||
| 265 | (offset (cdr langentry))) | ||
| 266 | (c-set-offset langelem offset) | ||
| 267 | ))) | ||
| 268 | c-file-offsets))) | ||
| 269 | |||
| 270 | (add-hook 'hack-local-variables-hook 'c-postprocess-file-styles) | ||
| 271 | |||
| 272 | |||
| 273 | ;; Common routines | ||
| 274 | (defsubst c-make-inherited-keymap () | ||
| 275 | (let ((map (make-sparse-keymap))) | ||
| 276 | (cond | ||
| 277 | ;; XEmacs 19 & 20 | ||
| 278 | ((fboundp 'set-keymap-parents) | ||
| 279 | (set-keymap-parents map c-mode-base-map)) | ||
| 280 | ;; Emacs 19 | ||
| 281 | ((fboundp 'set-keymap-parent) | ||
| 282 | (set-keymap-parent map c-mode-base-map)) | ||
| 283 | ;; incompatible | ||
| 284 | (t (error "CC Mode is incompatible with this version of Emacs"))) | ||
| 285 | map)) | ||
| 286 | |||
| 287 | (defun c-populate-syntax-table (table) | ||
| 288 | ;; Populate the syntax TABLE | ||
| 289 | ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS! | ||
| 290 | (modify-syntax-entry ?_ "_" table) | ||
| 291 | (modify-syntax-entry ?\\ "\\" table) | ||
| 292 | (modify-syntax-entry ?+ "." table) | ||
| 293 | (modify-syntax-entry ?- "." table) | ||
| 294 | (modify-syntax-entry ?= "." table) | ||
| 295 | (modify-syntax-entry ?% "." table) | ||
| 296 | (modify-syntax-entry ?< "." table) | ||
| 297 | (modify-syntax-entry ?> "." table) | ||
| 298 | (modify-syntax-entry ?& "." table) | ||
| 299 | (modify-syntax-entry ?| "." table) | ||
| 300 | (modify-syntax-entry ?\' "\"" table)) | ||
| 301 | |||
| 302 | (defun c-setup-dual-comments (table) | ||
| 303 | ;; Set up TABLE to handle block and line style comments | ||
| 304 | (cond | ||
| 305 | ;; XEmacs 19 & 20 | ||
| 306 | ((memq '8-bit c-emacs-features) | ||
| 307 | (modify-syntax-entry ?/ ". 1456" table) | ||
| 308 | (modify-syntax-entry ?* ". 23" table) | ||
| 309 | (modify-syntax-entry ?\n "> b" table) | ||
| 310 | ;; Give CR the same syntax as newline, for selective-display | ||
| 311 | (modify-syntax-entry ?\^m "> b" table)) | ||
| 312 | ;; Emacs 19 | ||
| 313 | ((memq '1-bit c-emacs-features) | ||
| 314 | (modify-syntax-entry ?/ ". 124b" table) | ||
| 315 | (modify-syntax-entry ?* ". 23" table) | ||
| 316 | (modify-syntax-entry ?\n "> b" table) | ||
| 317 | ;; Give CR the same syntax as newline, for selective-display | ||
| 318 | (modify-syntax-entry ?\^m "> b" table)) | ||
| 319 | ;; incompatible | ||
| 320 | (t (error "CC Mode is incompatible with this version of Emacs")) | ||
| 321 | )) | ||
| 322 | |||
| 323 | (defvar c-mode-base-map () | ||
| 324 | "Keymap shared by all CC Mode related modes.") | ||
| 325 | |||
| 326 | (if c-mode-base-map | ||
| 327 | nil | ||
| 328 | ;; TBD: should we even worry about naming this keymap. My vote: no, | ||
| 329 | ;; because Emacs and XEmacs do it differently. | ||
| 330 | (setq c-mode-base-map (make-sparse-keymap)) | ||
| 331 | ;; put standard keybindings into MAP | ||
| 332 | ;; the following mappings correspond more or less directly to BOCM | ||
| 333 | (define-key c-mode-base-map "{" 'c-electric-brace) | ||
| 334 | (define-key c-mode-base-map "}" 'c-electric-brace) | ||
| 335 | (define-key c-mode-base-map ";" 'c-electric-semi&comma) | ||
| 336 | (define-key c-mode-base-map "#" 'c-electric-pound) | ||
| 337 | (define-key c-mode-base-map ":" 'c-electric-colon) | ||
| 338 | ;; Lucid Emacs 19.9 defined these two, the second of which was | ||
| 339 | ;; commented out... | ||
| 340 | ;; (define-key c-mode-base-map "\e{" 'c-insert-braces) | ||
| 341 | ;; Commented out electric square brackets because nobody likes them. | ||
| 342 | ;; (define-key c-mode-base-map "[" 'c-insert-brackets) | ||
| 343 | (define-key c-mode-base-map "\C-c\C-m" 'c-mark-function) | ||
| 344 | (define-key c-mode-base-map "\e\C-q" 'c-indent-exp) | ||
| 345 | (define-key c-mode-base-map "\ea" 'c-beginning-of-statement) | ||
| 346 | (define-key c-mode-base-map "\ee" 'c-end-of-statement) | ||
| 347 | (define-key c-mode-base-map "\C-c\C-n" 'c-forward-conditional) | ||
| 348 | (define-key c-mode-base-map "\C-c\C-p" 'c-backward-conditional) | ||
| 349 | (define-key c-mode-base-map "\C-c\C-u" 'c-up-conditional) | ||
| 350 | (define-key c-mode-base-map "\t" 'c-indent-command) | ||
| 351 | ;; Caution! Enter here at your own risk. We are trying to support | ||
| 352 | ;; several behaviors and it gets disgusting. :-( | ||
| 353 | ;; | ||
| 354 | ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind | ||
| 355 | ;; backwards deletion behavior to DEL, which both Delete and | ||
| 356 | ;; Backspace get translated to. There's no way to separate this | ||
| 357 | ;; behavior in a clean way, so deal with it! Besides, it's been | ||
| 358 | ;; this way since the dawn of BOCM. | ||
| 359 | (if (not (boundp 'delete-key-deletes-forward)) | ||
| 360 | (define-key c-mode-base-map "\177" 'c-electric-backspace) | ||
| 361 | ;; However, XEmacs 20 actually achieved enlightenment. It is | ||
| 362 | ;; possible to sanely define both backward and forward deletion | ||
| 363 | ;; behavior under X separately (TTYs are forever beyond hope, but | ||
| 364 | ;; who cares? XEmacs 20 does the right thing with these too). | ||
| 365 | (define-key c-mode-base-map [delete] 'c-electric-delete) | ||
| 366 | (define-key c-mode-base-map [backspace] 'c-electric-backspace)) | ||
| 367 | ;; these are new keybindings, with no counterpart to BOCM | ||
| 368 | (define-key c-mode-base-map "," 'c-electric-semi&comma) | ||
| 369 | (define-key c-mode-base-map "*" 'c-electric-star) | ||
| 370 | (define-key c-mode-base-map "\C-c\C-q" 'c-indent-defun) | ||
| 371 | (define-key c-mode-base-map "\C-c\C-\\" 'c-backslash-region) | ||
| 372 | ;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature | ||
| 373 | (define-key c-mode-base-map "\C-c\C-a" 'c-toggle-auto-state) | ||
| 374 | (define-key c-mode-base-map "\C-c\C-b" 'c-submit-bug-report) | ||
| 375 | (define-key c-mode-base-map "\C-c\C-c" 'comment-region) | ||
| 376 | (define-key c-mode-base-map "\C-c\C-d" 'c-toggle-hungry-state) | ||
| 377 | (define-key c-mode-base-map "\C-c\C-e" 'c-macro-expand) | ||
| 378 | (define-key c-mode-base-map "\C-c\C-o" 'c-set-offset) | ||
| 379 | (define-key c-mode-base-map "\C-c\C-s" 'c-show-syntactic-information) | ||
| 380 | (define-key c-mode-base-map "\C-c\C-t" 'c-toggle-auto-hungry-state) | ||
| 381 | (define-key c-mode-base-map "\C-c." 'c-set-style) | ||
| 382 | ;; conflicts with OOBR | ||
| 383 | ;;(define-key c-mode-base-map "\C-c\C-v" 'c-version) | ||
| 384 | ) | ||
| 385 | |||
| 386 | ;; menu support for both XEmacs and Emacs. If you don't have easymenu | ||
| 387 | ;; with your version of Emacs, you are incompatible! | ||
| 388 | (require 'easymenu) | ||
| 389 | |||
| 390 | (defvar c-c-menu nil) | ||
| 391 | (defvar c-c++-menu nil) | ||
| 392 | (defvar c-objc-menu nil) | ||
| 393 | (defvar c-java-menu nil) | ||
| 394 | |||
| 395 | (defun c-mode-menu (modestr) | ||
| 396 | (let ((m | ||
| 397 | '(["Comment Out Region" comment-region (mark)] | ||
| 398 | ["Macro Expand Region" c-macro-expand (mark)] | ||
| 399 | ["Backslashify" c-backslash-region (mark)] | ||
| 400 | ["Indent Expression" c-indent-exp | ||
| 401 | (memq (char-after) '(?\( ?\[ ?\{))] | ||
| 402 | ["Indent Line" c-indent-command t] | ||
| 403 | ["Fill Comment Paragraph" c-fill-paragraph t] | ||
| 404 | ["Up Conditional" c-up-conditional t] | ||
| 405 | ["Backward Conditional" c-backward-conditional t] | ||
| 406 | ["Forward Conditional" c-forward-conditional t] | ||
| 407 | ["Backward Statement" c-beginning-of-statement t] | ||
| 408 | ["Forward Statement" c-end-of-statement t] | ||
| 409 | ))) | ||
| 410 | (cons modestr m))) | ||
| 411 | |||
| 412 | |||
| 413 | |||
| 414 | ;; Support for C | ||
| 415 | |||
| 416 | (defvar c-mode-abbrev-table nil | ||
| 417 | "Abbrev table in use in c-mode buffers.") | ||
| 418 | (define-abbrev-table 'c-mode-abbrev-table ()) | ||
| 419 | |||
| 420 | (defvar c-mode-map () | ||
| 421 | "Keymap used in c-mode buffers.") | ||
| 422 | (if c-mode-map | ||
| 423 | nil | ||
| 424 | (setq c-mode-map (c-make-inherited-keymap)) | ||
| 425 | ;; add bindings which are only useful for C | ||
| 426 | ) | ||
| 427 | |||
| 428 | ;;;###autoload | ||
| 429 | (defvar c-mode-syntax-table nil | ||
| 430 | "Syntax table used in c-mode buffers.") | ||
| 431 | (if c-mode-syntax-table | ||
| 432 | () | ||
| 433 | (setq c-mode-syntax-table (make-syntax-table)) | ||
| 434 | (c-populate-syntax-table c-mode-syntax-table) | ||
| 435 | ;; add extra comment syntax | ||
| 436 | (modify-syntax-entry ?/ ". 14" c-mode-syntax-table) | ||
| 437 | (modify-syntax-entry ?* ". 23" c-mode-syntax-table)) | ||
| 438 | |||
| 439 | (defun c-enable-//-in-c-mode () | ||
| 440 | "Enables // as a comment delimiter in `c-mode'. | ||
| 441 | ANSI C currently does *not* allow this, although many C compilers | ||
| 442 | support optional C++ style comments. To use, call this function from | ||
| 443 | your `.emacs' file before you visit any C files. The changes are | ||
| 444 | global and affect all future `c-mode' buffers." | ||
| 445 | (c-setup-dual-comments c-mode-syntax-table) | ||
| 446 | (setq-default c-C-comment-start-regexp c-C++-comment-start-regexp)) | ||
| 447 | |||
| 448 | (easy-menu-define c-c-menu c-mode-map "C Mode Commands" | ||
| 449 | (c-mode-menu "C")) | ||
| 450 | |||
| 451 | |||
| 452 | ;; Support for C++ | ||
| 453 | |||
| 454 | (defvar c++-mode-abbrev-table nil | ||
| 455 | "Abbrev table in use in c++-mode buffers.") | ||
| 456 | (define-abbrev-table 'c++-mode-abbrev-table ()) | ||
| 457 | |||
| 458 | (defvar c++-mode-map () | ||
| 459 | "Keymap used in c++-mode buffers.") | ||
| 460 | (if c++-mode-map | ||
| 461 | nil | ||
| 462 | (setq c++-mode-map (c-make-inherited-keymap)) | ||
| 463 | ;; add bindings which are only useful for C++ | ||
| 464 | (define-key c++-mode-map "\C-c:" 'c-scope-operator) | ||
| 465 | (define-key c++-mode-map "/" 'c-electric-slash) | ||
| 466 | (define-key c++-mode-map "<" 'c-electric-lt-gt) | ||
| 467 | (define-key c++-mode-map ">" 'c-electric-lt-gt)) | ||
| 468 | |||
| 469 | (defvar c++-mode-syntax-table nil | ||
| 470 | "Syntax table used in c++-mode buffers.") | ||
| 471 | (if c++-mode-syntax-table | ||
| 472 | () | ||
| 473 | (setq c++-mode-syntax-table (make-syntax-table)) | ||
| 474 | (c-populate-syntax-table c++-mode-syntax-table) | ||
| 475 | ;; add extra comment syntax | ||
| 476 | (c-setup-dual-comments c++-mode-syntax-table) | ||
| 477 | ;; TBD: does it make sense for colon to be symbol class in C++? | ||
| 478 | ;; I'm not so sure, since c-label-key is busted on lines like: | ||
| 479 | ;; Foo::bar( i ); | ||
| 480 | ;; maybe c-label-key should be fixed instead of commenting this out, | ||
| 481 | ;; but it also bothers me that this only seems appropriate for C++ | ||
| 482 | ;; and not C. | ||
| 483 | ;;(modify-syntax-entry ?: "_" c++-mode-syntax-table) | ||
| 484 | ) | ||
| 485 | |||
| 486 | (easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands" | ||
| 487 | (c-mode-menu "C++")) | ||
| 488 | |||
| 489 | |||
| 490 | ;; Support for Objective-C | ||
| 491 | |||
| 492 | (defvar objc-mode-abbrev-table nil | ||
| 493 | "Abbrev table in use in objc-mode buffers.") | ||
| 494 | (define-abbrev-table 'objc-mode-abbrev-table ()) | ||
| 495 | |||
| 496 | (defvar objc-mode-map () | ||
| 497 | "Keymap used in objc-mode buffers.") | ||
| 498 | (if objc-mode-map | ||
| 499 | nil | ||
| 500 | (setq objc-mode-map (c-make-inherited-keymap)) | ||
| 501 | ;; add bindings which are only useful for Objective-C | ||
| 502 | (define-key objc-mode-map "/" 'c-electric-slash)) | ||
| 503 | |||
| 504 | (defvar objc-mode-syntax-table nil | ||
| 505 | "Syntax table used in objc-mode buffers.") | ||
| 506 | (if objc-mode-syntax-table | ||
| 507 | () | ||
| 508 | (setq objc-mode-syntax-table (make-syntax-table)) | ||
| 509 | (c-populate-syntax-table objc-mode-syntax-table) | ||
| 510 | ;; add extra comment syntax | ||
| 511 | (c-setup-dual-comments objc-mode-syntax-table) | ||
| 512 | ;; everyone gets these | ||
| 513 | (modify-syntax-entry ?@ "_" objc-mode-syntax-table) | ||
| 514 | ) | ||
| 515 | |||
| 516 | (easy-menu-define c-objc-menu objc-mode-map "ObjC Mode Commands" | ||
| 517 | (c-mode-menu "ObjC")) | ||
| 518 | |||
| 519 | |||
| 520 | ;; Support for Java | ||
| 521 | |||
| 522 | (defvar java-mode-abbrev-table nil | ||
| 523 | "Abbrev table in use in java-mode buffers.") | ||
| 524 | (define-abbrev-table 'java-mode-abbrev-table ()) | ||
| 525 | |||
| 526 | (defvar java-mode-map () | ||
| 527 | "Keymap used in java-mode buffers.") | ||
| 528 | (if java-mode-map | ||
| 529 | nil | ||
| 530 | (setq java-mode-map (c-make-inherited-keymap)) | ||
| 531 | ;; add bindings which are only useful for Java | ||
| 532 | (define-key java-mode-map "/" 'c-electric-slash)) | ||
| 533 | |||
| 534 | (defvar java-mode-syntax-table nil | ||
| 535 | "Syntax table used in java-mode buffers.") | ||
| 536 | (if java-mode-syntax-table | ||
| 537 | () | ||
| 538 | (setq java-mode-syntax-table (make-syntax-table)) | ||
| 539 | (c-populate-syntax-table java-mode-syntax-table) | ||
| 540 | ;; add extra comment syntax | ||
| 541 | (c-setup-dual-comments java-mode-syntax-table) | ||
| 542 | ;; everyone gets these | ||
| 543 | (modify-syntax-entry ?@ "_" java-mode-syntax-table) | ||
| 544 | ) | ||
| 545 | |||
| 546 | (easy-menu-define c-java-menu java-mode-map "Java Mode Commands" | ||
| 547 | (c-mode-menu "Java")) | ||
| 548 | |||
| 549 | |||
| 550 | (provide 'cc-langs) | ||
| 551 | ;;; cc-langs.el ends here | ||
diff --git a/lisp/progmodes/cc-menus.el b/lisp/progmodes/cc-menus.el new file mode 100644 index 00000000000..3f190a419b1 --- /dev/null +++ b/lisp/progmodes/cc-menus.el | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | ;;; cc-menus.el --- imenu support for 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.12 | ||
| 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 | ;; imenu integration | ||
| 32 | (defvar cc-imenu-c++-generic-expression | ||
| 33 | (` | ||
| 34 | ((nil | ||
| 35 | (, | ||
| 36 | (concat | ||
| 37 | "^" ; beginning of line is required | ||
| 38 | "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>" | ||
| 39 | "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; type specs; there can be no | ||
| 40 | "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; more than 3 tokens, right? | ||
| 41 | |||
| 42 | "\\(" ; last type spec including */& | ||
| 43 | "[a-zA-Z0-9_:]+" | ||
| 44 | "\\([ \t]*[*&]+[ \t]*\\|[ \t]+\\)" ; either ptr/ref sign or ws | ||
| 45 | "\\)?" ; if there is a last type spec | ||
| 46 | "\\(" ; name, take into the imenu entry | ||
| 47 | "[a-zA-Z0-9_:~]+" ; member func, ctor or dtor... | ||
| 48 | ; (may not contain * because then | ||
| 49 | ; "a::operator char*" would | ||
| 50 | ; become "char*"!) | ||
| 51 | "\\|" | ||
| 52 | "\\([a-zA-Z0-9_:~]*::\\)?operator" | ||
| 53 | "[^a-zA-Z1-9_][^(]*" ; ...or operator | ||
| 54 | " \\)" | ||
| 55 | "[ \t]*([^)]*)[ \t\n]*[^ ;]" ; require something other than | ||
| 56 | ; a `;' after the (...) to | ||
| 57 | ; avoid prototypes. Can't | ||
| 58 | ; catch cases with () inside | ||
| 59 | ; the parentheses surrounding | ||
| 60 | ; the parameters. e.g.: | ||
| 61 | ; "int foo(int a=bar()) {...}" | ||
| 62 | |||
| 63 | )) 6) | ||
| 64 | ("Class" | ||
| 65 | (, (concat | ||
| 66 | "^" ; beginning of line is required | ||
| 67 | "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>" | ||
| 68 | "class[ \t]+" | ||
| 69 | "\\([a-zA-Z0-9_]+\\)" ; the string we want to get | ||
| 70 | "[ \t]*[:{]" | ||
| 71 | )) 2))) | ||
| 72 | "Imenu generic expression for C++ mode. See `imenu-generic-expression'.") | ||
| 73 | |||
| 74 | (defvar cc-imenu-c-generic-expression | ||
| 75 | cc-imenu-c++-generic-expression | ||
| 76 | "Imenu generic expression for C mode. See `imenu-generic-expression'.") | ||
| 77 | |||
| 78 | ;(defvar cc-imenu-objc-generic-expression | ||
| 79 | ; ()) | ||
| 80 | ; Please contribute one! | ||
| 81 | |||
| 82 | (defvar cc-imenu-java-generic-expression | ||
| 83 | (` | ||
| 84 | ((nil | ||
| 85 | (, | ||
| 86 | (concat | ||
| 87 | "^\\([ \t]\\)*" | ||
| 88 | "\\([A-Za-z0-9_-]+[ \t]+\\)?" ; type specs; there can be | ||
| 89 | "\\([A-Za-z0-9_-]+[ \t]+\\)?" ; more than 3 tokens, right? | ||
| 90 | "\\([A-Za-z0-9_-]+[ \t]*[[]?[]]?\\)" | ||
| 91 | "\\([ \t]\\)" | ||
| 92 | "\\([A-Za-z0-9_-]+\\)" ; the string we want to get | ||
| 93 | "\\([ \t]*\\)+(" | ||
| 94 | "\\([a-zA-Z,_1-9\n \t]*[[]?[]]?\\)*" ; arguments | ||
| 95 | ")[ \t]*" | ||
| 96 | "[^;(]" | ||
| 97 | "[,a-zA-Z_1-9\n \t]*{" | ||
| 98 | )) 6))) | ||
| 99 | "Imenu generic expression for Java mode. See `imenu-generic-expression'.") | ||
| 100 | |||
| 101 | |||
| 102 | (provide 'cc-menus) | ||
| 103 | ;;; cc-menus.el ends here | ||
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el new file mode 100644 index 00000000000..b178a42e199 --- /dev/null +++ b/lisp/progmodes/cc-mode.el | |||
| @@ -0,0 +1,344 @@ | |||
| 1 | ;;; cc-mode.el --- major mode for editing C, C++, Objective-C, and Java code | ||
| 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: a long, long, time ago. adapted from the original c-mode.el | ||
| 10 | ;; Version: 5.12 | ||
| 11 | ;; Keywords: c languages oop | ||
| 12 | |||
| 13 | ;; NOTE: Read the commentary below for the right way to submit bug reports! | ||
| 14 | ;; NOTE: See the accompanying texinfo manual for details on using this mode! | ||
| 15 | |||
| 16 | ;; This file is part of GNU Emacs. | ||
| 17 | |||
| 18 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 19 | ;; it under the terms of the GNU General Public License as published by | ||
| 20 | ;; the Free Software Foundation; either version 2, or (at your option) | ||
| 21 | ;; any later version. | ||
| 22 | |||
| 23 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 24 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 25 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 26 | ;; GNU General Public License for more details. | ||
| 27 | |||
| 28 | ;; You should have received a copy of the GNU General Public License | ||
| 29 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | ||
| 30 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 31 | ;; Boston, MA 02111-1307, USA. | ||
| 32 | |||
| 33 | ;;; Commentary: | ||
| 34 | |||
| 35 | ;; This package provides GNU Emacs major modes for editing C, C++, | ||
| 36 | ;; Objective-C, and Java code. As of the latest Emacs and XEmacs | ||
| 37 | ;; releases, it is the default package for editing these languages. | ||
| 38 | ;; This package is called "CC Mode", and should be spelled exactly | ||
| 39 | ;; this way. It supports K&R and ANSI C, ANSI C++, Objective-C, and | ||
| 40 | ;; Java, with a consistent indentation model across all modes. This | ||
| 41 | ;; indentation model is intuitive and very flexible, so that almost | ||
| 42 | ;; any desired style of indentation can be supported. Installation, | ||
| 43 | ;; usage, and programming details are contained in an accompanying | ||
| 44 | ;; texinfo manual. | ||
| 45 | |||
| 46 | ;; CC Mode's immediate ancestors were, c++-mode.el, cplus-md.el, and | ||
| 47 | ;; cplus-md1.el.. | ||
| 48 | |||
| 49 | ;; NOTE: This mode does not perform font-locking (a.k.a syntactic | ||
| 50 | ;; coloring, keyword highlighting, etc.) for any of the supported | ||
| 51 | ;; modes. Typically this is done by a package called font-lock.el | ||
| 52 | ;; which I do *not* maintain. You should contact the Emacs | ||
| 53 | ;; maintainers for questions about coloring or highlighting in any | ||
| 54 | ;; language mode. | ||
| 55 | |||
| 56 | ;; To submit bug reports, type "C-c C-b". These will be sent to | ||
| 57 | ;; bug-gnu-emacs@prep.ai.mit.edu as well as cc-mode-help@python.org, | ||
| 58 | ;; and I'll read about them there (the former is mirrored as the | ||
| 59 | ;; Usenet newsgroup gnu.emacs.bug). Questions can sent to | ||
| 60 | ;; help-gnu-emacs@prep.ai.mit.edu (mirrored as gnu.emacs.help) and/or | ||
| 61 | ;; cc-mode-help@python.org. Please do not send bugs or questions to | ||
| 62 | ;; my personal account. | ||
| 63 | |||
| 64 | ;; YOU CAN IGNORE ALL BYTE-COMPILER WARNINGS. They are the result of | ||
| 65 | ;; the cross-Emacsen support. GNU Emacs 19 (from the FSF), GNU XEmacs | ||
| 66 | ;; 19 (formerly Lucid Emacs), and GNU Emacs 18 all do things | ||
| 67 | ;; differently and there's no way to shut the byte-compiler up at the | ||
| 68 | ;; necessary granularity. Let me say this again: YOU CAN IGNORE ALL | ||
| 69 | ;; BYTE-COMPILER WARNINGS (you'd be surprised at how many people don't | ||
| 70 | ;; follow this advice :-). | ||
| 71 | |||
| 72 | ;; Many, many thanks go out to all the folks on the beta test list. | ||
| 73 | ;; Without their patience, testing, insight, code contributions, and | ||
| 74 | ;; encouragement CC Mode would be a far inferior package. | ||
| 75 | |||
| 76 | ;; You can get the latest version of CC Mode, including PostScript | ||
| 77 | ;; documentation and separate individual files from: | ||
| 78 | ;; | ||
| 79 | ;; http://www.python.org/ftp/emacs/ | ||
| 80 | |||
| 81 | ;; Or if you don't have access to the World Wide Web, through | ||
| 82 | ;; anonymous ftp from: | ||
| 83 | ;; | ||
| 84 | ;; ftp://ftp.python.org/pub/emacs | ||
| 85 | |||
| 86 | ;;; Code: | ||
| 87 | |||
| 88 | (eval-when-compile | ||
| 89 | (require 'cc-menus)) | ||
| 90 | (require 'cc-defs) | ||
| 91 | |||
| 92 | |||
| 93 | ;;;###autoload | ||
| 94 | (defun c-mode () | ||
| 95 | "Major mode for editing K&R and ANSI C code. | ||
| 96 | To submit a problem report, enter `\\[c-submit-bug-report]' from a | ||
| 97 | c-mode buffer. This automatically sets up a mail buffer with version | ||
| 98 | information already added. You just need to add a description of the | ||
| 99 | problem, including a reproducible test case and send the message. | ||
| 100 | |||
| 101 | To see what version of CC Mode you are running, enter `\\[c-version]'. | ||
| 102 | |||
| 103 | The hook variable `c-mode-hook' is run with no args, if that value is | ||
| 104 | bound and has a non-nil value. Also the hook `c-mode-common-hook' is | ||
| 105 | run first. | ||
| 106 | |||
| 107 | Key bindings: | ||
| 108 | \\{c-mode-map}" | ||
| 109 | (interactive) | ||
| 110 | (c-load-all) | ||
| 111 | (kill-all-local-variables) | ||
| 112 | (set-syntax-table c-mode-syntax-table) | ||
| 113 | (setq major-mode 'c-mode | ||
| 114 | mode-name "C" | ||
| 115 | local-abbrev-table c-mode-abbrev-table) | ||
| 116 | (use-local-map c-mode-map) | ||
| 117 | (c-common-init) | ||
| 118 | (setq comment-start "/* " | ||
| 119 | comment-end " */" | ||
| 120 | comment-multi-line t | ||
| 121 | c-conditional-key c-C-conditional-key | ||
| 122 | c-class-key c-C-class-key | ||
| 123 | c-baseclass-key nil | ||
| 124 | c-comment-start-regexp c-C-comment-start-regexp | ||
| 125 | imenu-generic-expression cc-imenu-c-generic-expression) | ||
| 126 | (run-hooks 'c-mode-common-hook) | ||
| 127 | (run-hooks 'c-mode-hook) | ||
| 128 | (c-update-modeline)) | ||
| 129 | |||
| 130 | |||
| 131 | ;;;###autoload | ||
| 132 | (defun c++-mode () | ||
| 133 | "Major mode for editing C++ code. | ||
| 134 | To submit a problem report, enter `\\[c-submit-bug-report]' from a | ||
| 135 | c++-mode buffer. This automatically sets up a mail buffer with | ||
| 136 | version information already added. You just need to add a description | ||
| 137 | of the problem, including a reproducible test case, and send the | ||
| 138 | message. | ||
| 139 | |||
| 140 | To see what version of CC Mode you are running, enter `\\[c-version]'. | ||
| 141 | |||
| 142 | The hook variable `c++-mode-hook' is run with no args, if that | ||
| 143 | variable is bound and has a non-nil value. Also the hook | ||
| 144 | `c-mode-common-hook' is run first. | ||
| 145 | |||
| 146 | Key bindings: | ||
| 147 | \\{c++-mode-map}" | ||
| 148 | (interactive) | ||
| 149 | (c-load-all) | ||
| 150 | (kill-all-local-variables) | ||
| 151 | (set-syntax-table c++-mode-syntax-table) | ||
| 152 | (setq major-mode 'c++-mode | ||
| 153 | mode-name "C++" | ||
| 154 | local-abbrev-table c++-mode-abbrev-table) | ||
| 155 | (use-local-map c++-mode-map) | ||
| 156 | (c-common-init) | ||
| 157 | (setq comment-start "// " | ||
| 158 | comment-end "" | ||
| 159 | comment-multi-line nil | ||
| 160 | c-conditional-key c-C++-conditional-key | ||
| 161 | c-comment-start-regexp c-C++-comment-start-regexp | ||
| 162 | c-class-key c-C++-class-key | ||
| 163 | c-access-key c-C++-access-key | ||
| 164 | c-double-slash-is-comments-p t | ||
| 165 | c-recognize-knr-p nil | ||
| 166 | imenu-generic-expression cc-imenu-c++-generic-expression) | ||
| 167 | (run-hooks 'c-mode-common-hook) | ||
| 168 | (run-hooks 'c++-mode-hook) | ||
| 169 | (c-update-modeline)) | ||
| 170 | |||
| 171 | |||
| 172 | ;;;###autoload | ||
| 173 | (defun objc-mode () | ||
| 174 | "Major mode for editing Objective C code. | ||
| 175 | To submit a problem report, enter `\\[c-submit-bug-report]' from an | ||
| 176 | objc-mode buffer. This automatically sets up a mail buffer with | ||
| 177 | version information already added. You just need to add a description | ||
| 178 | of the problem, including a reproducible test case, and send the | ||
| 179 | message. | ||
| 180 | |||
| 181 | To see what version of CC Mode you are running, enter `\\[c-version]'. | ||
| 182 | |||
| 183 | The hook variable `objc-mode-hook' is run with no args, if that value | ||
| 184 | is bound and has a non-nil value. Also the hook `c-mode-common-hook' | ||
| 185 | is run first. | ||
| 186 | |||
| 187 | Key bindings: | ||
| 188 | \\{objc-mode-map}" | ||
| 189 | (interactive) | ||
| 190 | (c-load-all) | ||
| 191 | (kill-all-local-variables) | ||
| 192 | (set-syntax-table objc-mode-syntax-table) | ||
| 193 | (setq major-mode 'objc-mode | ||
| 194 | mode-name "ObjC" | ||
| 195 | local-abbrev-table objc-mode-abbrev-table) | ||
| 196 | (use-local-map objc-mode-map) | ||
| 197 | (c-common-init) | ||
| 198 | (setq comment-start "// " | ||
| 199 | comment-end "" | ||
| 200 | comment-multi-line nil | ||
| 201 | c-conditional-key c-C-conditional-key | ||
| 202 | c-comment-start-regexp c-C++-comment-start-regexp | ||
| 203 | c-class-key c-ObjC-class-key | ||
| 204 | c-baseclass-key nil | ||
| 205 | c-access-key c-ObjC-access-key | ||
| 206 | c-double-slash-is-comments-p t | ||
| 207 | c-method-key c-ObjC-method-key) | ||
| 208 | (run-hooks 'c-mode-common-hook) | ||
| 209 | (run-hooks 'objc-mode-hook) | ||
| 210 | (c-update-modeline)) | ||
| 211 | |||
| 212 | |||
| 213 | ;;;###autoload | ||
| 214 | (defun java-mode () | ||
| 215 | "Major mode for editing Java code. | ||
| 216 | To submit a problem report, enter `\\[c-submit-bug-report]' from an | ||
| 217 | java-mode buffer. This automatically sets up a mail buffer with | ||
| 218 | version information already added. You just need to add a description | ||
| 219 | of the problem, including a reproducible test case and send the | ||
| 220 | message. | ||
| 221 | |||
| 222 | To see what version of CC Mode you are running, enter `\\[c-version]'. | ||
| 223 | |||
| 224 | The hook variable `java-mode-hook' is run with no args, if that value | ||
| 225 | is bound and has a non-nil value. Also the common hook | ||
| 226 | `c-mode-common-hook' is run first. Note that this mode automatically | ||
| 227 | sets the \"java\" style before calling any hooks so be careful if you | ||
| 228 | set styles in `c-mode-common-hook'. | ||
| 229 | |||
| 230 | Key bindings: | ||
| 231 | \\{java-mode-map}" | ||
| 232 | (interactive) | ||
| 233 | (c-load-all) | ||
| 234 | (kill-all-local-variables) | ||
| 235 | (set-syntax-table java-mode-syntax-table) | ||
| 236 | (setq major-mode 'java-mode | ||
| 237 | mode-name "Java" | ||
| 238 | local-abbrev-table java-mode-abbrev-table) | ||
| 239 | (use-local-map java-mode-map) | ||
| 240 | (c-common-init) | ||
| 241 | (setq comment-start "// " | ||
| 242 | comment-end "" | ||
| 243 | comment-multi-line nil | ||
| 244 | c-conditional-key c-Java-conditional-key | ||
| 245 | c-comment-start-regexp c-Java-comment-start-regexp | ||
| 246 | c-class-key c-Java-class-key | ||
| 247 | c-method-key c-Java-method-key | ||
| 248 | c-double-slash-is-comments-p t | ||
| 249 | c-baseclass-key nil | ||
| 250 | c-recognize-knr-p nil | ||
| 251 | c-access-key c-Java-access-key | ||
| 252 | ;defun-prompt-regexp c-Java-defun-prompt-regexp | ||
| 253 | imenu-generic-expression cc-imenu-java-generic-expression | ||
| 254 | ) | ||
| 255 | (c-set-style "java") | ||
| 256 | (run-hooks 'c-mode-common-hook) | ||
| 257 | (run-hooks 'java-mode-hook) | ||
| 258 | (c-update-modeline)) | ||
| 259 | |||
| 260 | |||
| 261 | ;; defuns for submitting bug reports | ||
| 262 | (defconst c-version "5.12" | ||
| 263 | "CC Mode version number.") | ||
| 264 | |||
| 265 | (defconst c-mode-help-address | ||
| 266 | "bug-gnu-emacs@prep.ai.mit.edu, cc-mode-help@python.org" | ||
| 267 | "Address for CC Mode bug reports.") | ||
| 268 | |||
| 269 | (defun c-version () | ||
| 270 | "Echo the current version of CC Mode in the minibuffer." | ||
| 271 | (interactive) | ||
| 272 | (message "Using CC Mode version %s" c-version) | ||
| 273 | (c-keep-region-active)) | ||
| 274 | |||
| 275 | ;; Get reporter-submit-bug-report when byte-compiling | ||
| 276 | (eval-when-compile | ||
| 277 | (require 'reporter)) | ||
| 278 | |||
| 279 | (defun c-submit-bug-report () | ||
| 280 | "Submit via mail a bug report on CC Mode." | ||
| 281 | (interactive) | ||
| 282 | (require 'cc-vars) | ||
| 283 | ;; load in reporter | ||
| 284 | (let ((reporter-prompt-for-summary-p t) | ||
| 285 | (reporter-dont-compact-list '(c-offsets-alist)) | ||
| 286 | (style c-indentation-style) | ||
| 287 | (hook c-special-indent-hook) | ||
| 288 | (c-features c-emacs-features)) | ||
| 289 | (and | ||
| 290 | (if (y-or-n-p "Do you want to submit a report on CC Mode? ") | ||
| 291 | t (message "") nil) | ||
| 292 | (require 'reporter) | ||
| 293 | (reporter-submit-bug-report | ||
| 294 | c-mode-help-address | ||
| 295 | (concat "CC Mode " c-version " (" | ||
| 296 | (cond ((eq major-mode 'c++-mode) "C++") | ||
| 297 | ((eq major-mode 'c-mode) "C") | ||
| 298 | ((eq major-mode 'objc-mode) "ObjC") | ||
| 299 | ((eq major-mode 'java-mode) "Java") | ||
| 300 | ) | ||
| 301 | ")") | ||
| 302 | (let ((vars (list | ||
| 303 | ;; report only the vars that affect indentation | ||
| 304 | 'c-basic-offset | ||
| 305 | 'c-offsets-alist | ||
| 306 | 'c-cleanup-list | ||
| 307 | 'c-comment-only-line-offset | ||
| 308 | 'c-backslash-column | ||
| 309 | 'c-delete-function | ||
| 310 | 'c-electric-pound-behavior | ||
| 311 | 'c-hanging-braces-alist | ||
| 312 | 'c-hanging-colons-alist | ||
| 313 | 'c-hanging-comment-starter-p | ||
| 314 | 'c-hanging-comment-ender-p | ||
| 315 | 'c-indent-comments-syntactically-p | ||
| 316 | 'c-tab-always-indent | ||
| 317 | 'c-recognize-knr-p | ||
| 318 | 'c-label-minimum-indentation | ||
| 319 | 'defun-prompt-regexp | ||
| 320 | 'tab-width | ||
| 321 | ))) | ||
| 322 | (if (not (boundp 'defun-prompt-regexp)) | ||
| 323 | (delq 'defun-prompt-regexp vars) | ||
| 324 | vars)) | ||
| 325 | (function | ||
| 326 | (lambda () | ||
| 327 | (insert | ||
| 328 | "Buffer Style: " style "\n\n" | ||
| 329 | (if hook | ||
| 330 | (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" | ||
| 331 | "c-special-indent-hook is set to '" | ||
| 332 | (format "%s" hook) | ||
| 333 | ".\nPerhaps this is your problem?\n" | ||
| 334 | "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n") | ||
| 335 | "\n") | ||
| 336 | (format "c-emacs-features: %s\n" c-features) | ||
| 337 | ))) | ||
| 338 | nil | ||
| 339 | "Dear Barry," | ||
| 340 | )))) | ||
| 341 | |||
| 342 | |||
| 343 | (provide 'cc-mode) | ||
| 344 | ;;; cc-mode.el ends here | ||
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el new file mode 100644 index 00000000000..975796d7b79 --- /dev/null +++ b/lisp/progmodes/cc-styles.el | |||
| @@ -0,0 +1,617 @@ | |||
| 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.12 | ||
| 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 | |||
| 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. | ||
| 148 | Elements of this alist are of the form: | ||
| 149 | |||
| 150 | (STYLE-STRING [BASE-STYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...]) | ||
| 151 | |||
| 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. | ||
| 155 | |||
| 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. | ||
| 160 | |||
| 161 | Two variables are treated specially. When VARIABLE is | ||
| 162 | `c-offsets-alist', the VALUE is a list containing elements of the | ||
| 163 | form: | ||
| 164 | |||
| 165 | (SYNTACTIC-SYMBOL . OFFSET) | ||
| 166 | |||
| 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. | ||
| 170 | |||
| 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'. | ||
| 174 | |||
| 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.") | ||
| 179 | |||
| 180 | |||
| 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. | ||
| 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. | ||
| 233 | |||
| 234 | The variable `c-indentation-style' always contains the buffer's current | ||
| 235 | style 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. | ||
| 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: | ||
| 251 | |||
| 252 | ([BASESTYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...]) | ||
| 253 | |||
| 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." | ||
| 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 | |||
| 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. | ||
| 330 | As described below, each cons cell in this list has the form: | ||
| 331 | |||
| 332 | (SYNTACTIC-SYMBOL . OFFSET) | ||
| 333 | |||
| 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 | ||
| 342 | them. | ||
| 343 | |||
| 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. | ||
| 351 | |||
| 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 | ||
| 354 | element is ignored. | ||
| 355 | |||
| 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. | ||
| 363 | |||
| 364 | Here 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 | |||
| 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 | |||
| 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." | ||
| 508 | (interactive | ||
| 509 | (let* ((langelem | ||
| 510 | (intern (completing-read | ||
| 511 | (concat "Syntactic symbol to change" | ||
| 512 | (if current-prefix-arg " or add" "") | ||
| 513 | ": ") | ||
| 514 | (mapcar | ||
| 515 | #'(lambda (langelem) | ||
| 516 | (cons (format "%s" (car langelem)) nil)) | ||
| 517 | c-offsets-alist) | ||
| 518 | nil (not current-prefix-arg) | ||
| 519 | ;; initial contents tries to be the last element | ||
| 520 | ;; on the syntactic analysis list for the current | ||
| 521 | ;; line | ||
| 522 | (let* ((syntax (c-guess-basic-syntax)) | ||
| 523 | (len (length syntax)) | ||
| 524 | (ic (format "%s" (car (nth (1- len) syntax))))) | ||
| 525 | (cons ic 0)) | ||
| 526 | ))) | ||
| 527 | (offset (c-read-offset langelem))) | ||
| 528 | (list langelem offset current-prefix-arg))) | ||
| 529 | ;; sanity check offset | ||
| 530 | (or (eq offset '+) | ||
| 531 | (eq offset '-) | ||
| 532 | (eq offset '++) | ||
| 533 | (eq offset '--) | ||
| 534 | (eq offset '*) | ||
| 535 | (eq offset '/) | ||
| 536 | (integerp offset) | ||
| 537 | (functionp offset) | ||
| 538 | (boundp offset) | ||
| 539 | (error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s" | ||
| 540 | offset)) | ||
| 541 | (let ((entry (assq symbol c-offsets-alist))) | ||
| 542 | (if entry | ||
| 543 | (setcdr entry offset) | ||
| 544 | (if add-p | ||
| 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)) | ||
| 548 | |||
| 549 | |||
| 550 | |||
| 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! | ||
| 556 | (require 'cl) | ||
| 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 | |||
| 616 | (provide 'cc-styles) | ||
| 617 | ;;; cc-styles.el ends here | ||
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el new file mode 100644 index 00000000000..96e1b809ab8 --- /dev/null +++ b/lisp/progmodes/cc-vars.el | |||
| @@ -0,0 +1,391 @@ | |||
| 1 | ;;; cc-vars.el --- user customization variables for 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.12 | ||
| 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 | (require 'custom) | ||
| 31 | |||
| 32 | |||
| 33 | (defcustom c-strict-syntax-p nil | ||
| 34 | "*If non-nil, all syntactic symbols must be found in `c-offsets-alist'. | ||
| 35 | If the syntactic symbol for a particular line does not match a symbol | ||
| 36 | in the offsets alist, an error is generated, otherwise no error is | ||
| 37 | reported and the syntactic symbol is ignored." | ||
| 38 | :type 'boolean | ||
| 39 | :group 'c) | ||
| 40 | |||
| 41 | (defcustom c-echo-syntactic-information-p nil | ||
| 42 | "*If non-nil, syntactic info is echoed when the line is indented." | ||
| 43 | :type 'boolean | ||
| 44 | :group 'c) | ||
| 45 | |||
| 46 | (defcustom c-basic-offset 4 | ||
| 47 | "*Amount of basic offset used by + and - symbols in `c-offsets-alist'." | ||
| 48 | :type 'integer | ||
| 49 | :group 'c) | ||
| 50 | |||
| 51 | (defcustom c-tab-always-indent t | ||
| 52 | "*Controls the operation of the TAB key. | ||
| 53 | If t, hitting TAB always just indents the current line. If nil, | ||
| 54 | hitting TAB indents the current line if point is at the left margin or | ||
| 55 | in the line's indentation, otherwise it insert a `real' tab character | ||
| 56 | \(see note\). If other than nil or t, then tab is inserted only | ||
| 57 | within literals -- defined as comments and strings -- and inside | ||
| 58 | preprocessor directives, but line is always reindented. | ||
| 59 | |||
| 60 | Note: The value of `indent-tabs-mode' will determine whether a real | ||
| 61 | tab character will be inserted, or the equivalent number of space. | ||
| 62 | When inserting a tab, actually the function stored in the variable | ||
| 63 | `c-insert-tab-function' is called. | ||
| 64 | |||
| 65 | Note: indentation of lines containing only comments is also controlled | ||
| 66 | by the `c-comment-only-line-offset' variable." | ||
| 67 | :type '(radio | ||
| 68 | :extra-offset 8 | ||
| 69 | :format "%{C Tab Always Indent%}:\n The TAB key:\n%v" | ||
| 70 | (const :tag "always indents, never inserts TAB" t) | ||
| 71 | (const :tag "indents in left margin, otherwise inserts TAB" nil) | ||
| 72 | (const :tag "inserts TAB in literals, otherwise indent" other)) | ||
| 73 | :group 'c) | ||
| 74 | |||
| 75 | (defcustom c-insert-tab-function 'insert-tab | ||
| 76 | "*Function used when inserting a tab for \\[TAB]. | ||
| 77 | Only used when `c-tab-always-indent' indicates a `real' tab character | ||
| 78 | should be inserted. Value must be a function taking no arguments." | ||
| 79 | :type 'function | ||
| 80 | :group 'c) | ||
| 81 | |||
| 82 | (defcustom c-comment-only-line-offset 0 | ||
| 83 | "*Extra offset for line which contains only the start of a comment. | ||
| 84 | Can contain an integer or a cons cell of the form: | ||
| 85 | |||
| 86 | (NON-ANCHORED-OFFSET . ANCHORED-OFFSET) | ||
| 87 | |||
| 88 | Where NON-ANCHORED-OFFSET is the amount of offset given to | ||
| 89 | non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is | ||
| 90 | the amount of offset to give column-zero anchored comment-only lines. | ||
| 91 | Just an integer as value is equivalent to (<val> . -1000)." | ||
| 92 | :type '(choice (integer :tag "Non-anchored offset") | ||
| 93 | (cons :tag "Non-anchored & anchored offset" | ||
| 94 | :value (0 . 0) | ||
| 95 | :extra-offset 8 | ||
| 96 | (integer :tag "Non-anchored offset") | ||
| 97 | (integer :tag "Anchored offset"))) | ||
| 98 | :group 'c) | ||
| 99 | |||
| 100 | (defcustom c-indent-comments-syntactically-p nil | ||
| 101 | "*Specifies how comment-only lines should be indented. | ||
| 102 | When this variable is non-nil, comment-only lines are indented | ||
| 103 | according to syntactic analysis via `c-offsets-alist', even when | ||
| 104 | \\[indent-for-comment] is used." | ||
| 105 | :type 'boolean | ||
| 106 | :group 'c) | ||
| 107 | |||
| 108 | (defcustom c-cleanup-list '(scope-operator) | ||
| 109 | "*List of various C/C++/ObjC constructs to \"clean up\". | ||
| 110 | These clean ups only take place when the auto-newline feature is | ||
| 111 | turned on, as evidenced by the `/a' or `/ah' appearing next to the | ||
| 112 | mode name. Valid symbols are: | ||
| 113 | |||
| 114 | brace-else-brace -- cleans up `} else {' constructs by placing entire | ||
| 115 | construct on a single line. This clean up | ||
| 116 | only takes place when there is nothing but | ||
| 117 | white space between the braces and the `else'. | ||
| 118 | Clean up occurs when the open-brace after the | ||
| 119 | `else' is typed. | ||
| 120 | brace-elseif-brace -- similar to brace-else-brace, but cleans up | ||
| 121 | `} else if {' constructs. | ||
| 122 | empty-defun-braces -- cleans up empty defun braces by placing the | ||
| 123 | braces on the same line. Clean up occurs when | ||
| 124 | the defun closing brace is typed. | ||
| 125 | defun-close-semi -- cleans up the terminating semi-colon on defuns | ||
| 126 | by placing the semi-colon on the same line as | ||
| 127 | the closing brace. Clean up occurs when the | ||
| 128 | semi-colon is typed. | ||
| 129 | list-close-comma -- cleans up commas following braces in array | ||
| 130 | and aggregate initializers. Clean up occurs | ||
| 131 | when the comma is typed. | ||
| 132 | scope-operator -- cleans up double colons which may designate | ||
| 133 | a C++ scope operator split across multiple | ||
| 134 | lines. Note that certain C++ constructs can | ||
| 135 | generate ambiguous situations. This clean up | ||
| 136 | only takes place when there is nothing but | ||
| 137 | whitespace between colons. Clean up occurs | ||
| 138 | when the second colon is typed." | ||
| 139 | :type '(set | ||
| 140 | :extra-offset 8 | ||
| 141 | (const :tag "Put `} else {' on one line" brace-else-brace) | ||
| 142 | (const :tag "Put `} else if {' on one line" brace-elseif-brace) | ||
| 143 | (const :tag "Put empty defun braces on one line" empty-defun-braces) | ||
| 144 | (const :tag "Put `},' in aggregates on one line" list-close-comma) | ||
| 145 | (const :tag "Put C++ style `::' on one line" scope-operator)) | ||
| 146 | :group 'c) | ||
| 147 | |||
| 148 | (defcustom c-hanging-braces-alist '((brace-list-open) | ||
| 149 | (substatement-open after) | ||
| 150 | (block-close . c-snug-do-while) | ||
| 151 | (extern-lang-open after) | ||
| 152 | ) | ||
| 153 | "*Controls the insertion of newlines before and after braces. | ||
| 154 | This variable contains an association list with elements of the | ||
| 155 | following form: (SYNTACTIC-SYMBOL . ACTION). | ||
| 156 | |||
| 157 | When a brace (either opening or closing) is inserted, the syntactic | ||
| 158 | context it defines is looked up in this list, and if found, the | ||
| 159 | associated ACTION is used to determine where newlines are inserted. | ||
| 160 | If the context is not found, the default is to insert a newline both | ||
| 161 | before and after the brace. | ||
| 162 | |||
| 163 | SYNTACTIC-SYMBOL can be any of: defun-open, defun-close, class-open, | ||
| 164 | class-close, inline-open, inline-close, block-open, block-close, | ||
| 165 | substatement-open, statement-case-open, extern-lang-open, | ||
| 166 | extern-lang-close, brace-list-open, brace-list-close, | ||
| 167 | brace-list-intro, or brace-list-entry. See `c-offsets-alist' for | ||
| 168 | details. | ||
| 169 | |||
| 170 | ACTION can be either a function symbol or a list containing any | ||
| 171 | combination of the symbols `before' or `after'. If the list is empty, | ||
| 172 | no newlines are inserted either before or after the brace. | ||
| 173 | |||
| 174 | When ACTION is a function symbol, the function is called with a two | ||
| 175 | arguments: the syntactic symbol for the brace and the buffer position | ||
| 176 | at which the brace was inserted. The function must return a list as | ||
| 177 | described in the preceding paragraph. Note that during the call to | ||
| 178 | the function, the variable `c-syntactic-context' is set to the entire | ||
| 179 | syntactic context for the brace line." | ||
| 180 | :type '(repeat | ||
| 181 | (cons :format "%v" | ||
| 182 | (choice :tag "Syntax" | ||
| 183 | (const defun-open) (const defun-close) | ||
| 184 | (const class-open) (const class-close) | ||
| 185 | (const inline-open) (const inline-close) | ||
| 186 | (const block-open) (const block-close) | ||
| 187 | (const substatement-open) (const statement-case-open) | ||
| 188 | (const extern-lang-open) (const extern-lang-close) | ||
| 189 | (const brace-list-open) (const brace-list-close) | ||
| 190 | (const brace-list-intro) (const brace-list-entry)) | ||
| 191 | (choice :tag "Action" | ||
| 192 | (set :format "Insert a newline %v" | ||
| 193 | :extra-offset 38 | ||
| 194 | (const :tag "before brace" before) | ||
| 195 | (const :tag "after brace" after)) | ||
| 196 | (function :format "Run function %v" :value c-) | ||
| 197 | ))) | ||
| 198 | :group 'c) | ||
| 199 | |||
| 200 | (defcustom c-hanging-colons-alist nil | ||
| 201 | "*Controls the insertion of newlines before and after certain colons. | ||
| 202 | This variable contains an association list with elements of the | ||
| 203 | following form: (SYNTACTIC-SYMBOL . ACTION). | ||
| 204 | |||
| 205 | SYNTACTIC-SYMBOL can be any of: case-label, label, access-label, | ||
| 206 | member-init-intro, or inher-intro. | ||
| 207 | |||
| 208 | See the variable `c-hanging-braces-alist' for the semantics of this | ||
| 209 | variable. Note however that making ACTION a function symbol is | ||
| 210 | currently not supported for this variable." | ||
| 211 | :type '(repeat | ||
| 212 | (cons :format "%v" | ||
| 213 | (choice :tag "Syntax" | ||
| 214 | (const case-label) (const label) (const access-label) | ||
| 215 | (const member-init-intro) (const inher-intro)) | ||
| 216 | (set :tag "Action" | ||
| 217 | :format "%t: %v" | ||
| 218 | :extra-offset 8 | ||
| 219 | (const before) (const after)))) | ||
| 220 | :group 'c) | ||
| 221 | |||
| 222 | (defcustom c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist) | ||
| 223 | "*List of functions that decide whether to insert a newline or not. | ||
| 224 | The functions in this list are called, in order, whenever the | ||
| 225 | auto-newline minor mode is activated (as evidenced by a `/a' or `/ah' | ||
| 226 | string in the mode line), and a semicolon or comma is typed (see | ||
| 227 | `c-electric-semi&comma'). Each function in this list is called with | ||
| 228 | no arguments, and should return one of the following values: | ||
| 229 | |||
| 230 | nil -- no determination made, continue checking | ||
| 231 | 'stop -- do not insert a newline, and stop checking | ||
| 232 | (anything else) -- insert a newline, and stop checking | ||
| 233 | |||
| 234 | If every function in the list is called with no determination made, | ||
| 235 | then no newline is inserted." | ||
| 236 | :type '(repeat function) | ||
| 237 | :group 'c) | ||
| 238 | |||
| 239 | (defcustom c-hanging-comment-ender-p t | ||
| 240 | "*Controls what \\[fill-paragraph] does to C block comment enders. | ||
| 241 | When set to nil, C block comment enders are left on their own line. | ||
| 242 | When set to t, block comment enders will be placed at the end of the | ||
| 243 | previous line (i.e. they `hang' on that line)." | ||
| 244 | :type 'boolean | ||
| 245 | :group 'c) | ||
| 246 | |||
| 247 | (defcustom c-hanging-comment-starter-p t | ||
| 248 | "*Controls what \\[fill-paragraph] does to C block comment starters. | ||
| 249 | When set to nil, C block comment starters are left on their own line. | ||
| 250 | When set to t, text that follows a block comment starter will be | ||
| 251 | placed on the same line as the block comment starter (i.e. the text | ||
| 252 | `hangs' on that line)." | ||
| 253 | :type 'boolean | ||
| 254 | :group 'c) | ||
| 255 | |||
| 256 | (defcustom c-backslash-column 48 | ||
| 257 | "*Column to insert backslashes when macroizing a region." | ||
| 258 | :type 'integer | ||
| 259 | :group 'c) | ||
| 260 | |||
| 261 | (defcustom c-special-indent-hook nil | ||
| 262 | "*Hook for user defined special indentation adjustments. | ||
| 263 | This hook gets called after a line is indented by the mode." | ||
| 264 | :type 'hook | ||
| 265 | :group 'c) | ||
| 266 | |||
| 267 | (defcustom c-backspace-function 'backward-delete-char-untabify | ||
| 268 | "*Function called by `c-electric-backspace' when deleting backwards." | ||
| 269 | :type 'function | ||
| 270 | :group 'c) | ||
| 271 | |||
| 272 | (defcustom c-delete-function 'delete-char | ||
| 273 | "*Function called by `c-electric-delete' when deleting forwards." | ||
| 274 | :type 'function | ||
| 275 | :group 'c) | ||
| 276 | |||
| 277 | (defcustom c-electric-pound-behavior nil | ||
| 278 | "*List of behaviors for electric pound insertion. | ||
| 279 | Only currently supported behavior is `alignleft'." | ||
| 280 | :type '(set :extra-offset 8 (const alignleft)) | ||
| 281 | :group 'c) | ||
| 282 | |||
| 283 | (defcustom c-label-minimum-indentation 1 | ||
| 284 | "*Minimum indentation for lines inside of top-level constructs. | ||
| 285 | This variable typically only affects code using the `gnu' style, which | ||
| 286 | mandates a minimum of one space in front of every line inside | ||
| 287 | top-level constructs. Specifically, the function | ||
| 288 | `c-gnu-impose-minimum' on your `c-special-indent-hook' is what | ||
| 289 | enforces this." | ||
| 290 | :type 'integer | ||
| 291 | :group 'c) | ||
| 292 | |||
| 293 | (defcustom c-progress-interval 5 | ||
| 294 | "*Interval used to update progress status during long re-indentation. | ||
| 295 | If a number, percentage complete gets updated after each interval of | ||
| 296 | that many seconds. Set to nil to inhibit updating. This is only | ||
| 297 | useful for Emacs 19." | ||
| 298 | :type 'integer | ||
| 299 | :group 'c) | ||
| 300 | |||
| 301 | (defcustom c-site-default-style "gnu" | ||
| 302 | "Default style for your site. | ||
| 303 | To change the default style at your site, you can set this variable to | ||
| 304 | any style defined in `c-style-alist'. However, if CC Mode is usually | ||
| 305 | loaded into your Emacs at compile time, you will need to set this | ||
| 306 | variable in the `site-init.el' file before CC Mode is loaded, then | ||
| 307 | re-dump Emacs." | ||
| 308 | :type 'string | ||
| 309 | :group 'c) | ||
| 310 | |||
| 311 | (defcustom c-style-variables-are-local-p nil | ||
| 312 | "*Whether style variables should be buffer local by default. | ||
| 313 | If non-nil, then all indentation style related variables will be made | ||
| 314 | buffer local by default. If nil, they will remain global. Variables | ||
| 315 | are made buffer local when this file is loaded, and once buffer | ||
| 316 | localized, they cannot be made global again. | ||
| 317 | |||
| 318 | The list of variables to buffer localize are: | ||
| 319 | c-offsets-alist | ||
| 320 | c-basic-offset | ||
| 321 | c-file-style | ||
| 322 | c-file-offsets | ||
| 323 | c-comment-only-line-offset | ||
| 324 | c-cleanup-list | ||
| 325 | c-hanging-braces-alist | ||
| 326 | c-hanging-colons-alist | ||
| 327 | c-hanging-comment-starter-p | ||
| 328 | c-hanging-comment-ender-p | ||
| 329 | c-backslash-column | ||
| 330 | c-label-minimum-indentation | ||
| 331 | c-special-indent-hook | ||
| 332 | c-indentation-style" | ||
| 333 | :type 'boolean | ||
| 334 | :group 'c) | ||
| 335 | |||
| 336 | (defcustom c-mode-hook nil | ||
| 337 | "*Hook called by `c-mode'." | ||
| 338 | :type '(hook :format "%{C Mode Hook%}:\n%v") | ||
| 339 | :group 'c) | ||
| 340 | |||
| 341 | (defcustom c++-mode-hook nil | ||
| 342 | "*Hook called by `c++-mode'." | ||
| 343 | :type 'hook | ||
| 344 | :group 'c) | ||
| 345 | |||
| 346 | (defcustom objc-mode-hook nil | ||
| 347 | "*Hook called by `objc-mode'." | ||
| 348 | :type 'hook | ||
| 349 | :group 'c) | ||
| 350 | |||
| 351 | (defcustom java-mode-hook nil | ||
| 352 | "*Hook called by `java-mode'." | ||
| 353 | :type 'hook | ||
| 354 | :group 'c) | ||
| 355 | |||
| 356 | (defcustom c-mode-common-hook nil | ||
| 357 | "*Hook called by all CC Mode modes for common initializations." | ||
| 358 | :type '(hook :format "%{CC Mode Common Hook%}:\n%v") | ||
| 359 | :group 'c) | ||
| 360 | |||
| 361 | |||
| 362 | |||
| 363 | ;; Non-customizable variables, still part of the interface to CC Mode | ||
| 364 | (defvar c-file-style nil | ||
| 365 | "Variable interface for setting style via File Local Variables. | ||
| 366 | In a file's Local Variable section, you can set this variable to a | ||
| 367 | string suitable for `c-set-style'. When the file is visited, CC Mode | ||
| 368 | will set the style of the file to this value automatically. | ||
| 369 | |||
| 370 | Note that file style settings are applied before file offset settings | ||
| 371 | as designated in the variable `c-file-offsets'.") | ||
| 372 | |||
| 373 | (defvar c-file-offsets nil | ||
| 374 | "Variable interface for setting offsets via File Local Variables. | ||
| 375 | In a file's Local Variable section, you can set this variable to an | ||
| 376 | association list similar to the values allowed in `c-offsets-alist'. | ||
| 377 | When the file is visited, CC Mode will institute these offset settings | ||
| 378 | automatically. | ||
| 379 | |||
| 380 | Note that file offset settings are applied after file style settings | ||
| 381 | as designated in the variable `c-file-style'.") | ||
| 382 | |||
| 383 | (defvar c-syntactic-context nil | ||
| 384 | "Variable containing syntactic analysis list during indentation.") | ||
| 385 | |||
| 386 | (defvar c-indentation-style c-site-default-style | ||
| 387 | "Name of style installed in the current buffer.") | ||
| 388 | |||
| 389 | |||
| 390 | (provide 'cc-vars) | ||
| 391 | ;;; cc-vars.el ends here | ||