|
|
1.1 ! root 1: ;; C code editing commands for Emacs ! 2: ;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc. ! 3: ! 4: ;; This file is part of GNU Emacs. ! 5: ! 6: ;; GNU Emacs is free software; you can redistribute it and/or modify ! 7: ;; it under the terms of the GNU General Public License as published by ! 8: ;; the Free Software Foundation; either version 1, or (at your option) ! 9: ;; any later version. ! 10: ! 11: ;; GNU Emacs is distributed in the hope that it will be useful, ! 12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: ;; GNU General Public License for more details. ! 15: ! 16: ;; You should have received a copy of the GNU General Public License ! 17: ;; along with GNU Emacs; see the file COPYING. If not, write to ! 18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 19: ! 20: ! 21: (defvar c-mode-abbrev-table nil ! 22: "Abbrev table in use in C-mode buffers.") ! 23: (define-abbrev-table 'c-mode-abbrev-table ()) ! 24: ! 25: (defvar c-mode-map () ! 26: "Keymap used in C mode.") ! 27: (if c-mode-map ! 28: () ! 29: (setq c-mode-map (make-sparse-keymap)) ! 30: (define-key c-mode-map "{" 'electric-c-brace) ! 31: (define-key c-mode-map "}" 'electric-c-brace) ! 32: (define-key c-mode-map ";" 'electric-c-semi) ! 33: (define-key c-mode-map ":" 'electric-c-terminator) ! 34: (define-key c-mode-map "\e\C-h" 'mark-c-function) ! 35: (define-key c-mode-map "\e\C-q" 'indent-c-exp) ! 36: (define-key c-mode-map "\177" 'backward-delete-char-untabify) ! 37: (define-key c-mode-map "\t" 'c-indent-command)) ! 38: ! 39: (autoload 'c-macro-expand "cmacexp" ! 40: "Display the result of expanding all C macros occurring in the region. ! 41: The expansion is entirely correct because it uses the C preprocessor." ! 42: t) ! 43: ! 44: (defvar c-mode-syntax-table nil ! 45: "Syntax table in use in C-mode buffers.") ! 46: ! 47: (if c-mode-syntax-table ! 48: () ! 49: (setq c-mode-syntax-table (make-syntax-table)) ! 50: (modify-syntax-entry ?\\ "\\" c-mode-syntax-table) ! 51: (modify-syntax-entry ?/ ". 14" c-mode-syntax-table) ! 52: (modify-syntax-entry ?* ". 23" c-mode-syntax-table) ! 53: (modify-syntax-entry ?+ "." c-mode-syntax-table) ! 54: (modify-syntax-entry ?- "." c-mode-syntax-table) ! 55: (modify-syntax-entry ?= "." c-mode-syntax-table) ! 56: (modify-syntax-entry ?% "." c-mode-syntax-table) ! 57: (modify-syntax-entry ?< "." c-mode-syntax-table) ! 58: (modify-syntax-entry ?> "." c-mode-syntax-table) ! 59: (modify-syntax-entry ?& "." c-mode-syntax-table) ! 60: (modify-syntax-entry ?| "." c-mode-syntax-table) ! 61: (modify-syntax-entry ?\' "\"" c-mode-syntax-table)) ! 62: ! 63: (defconst c-indent-level 2 ! 64: "*Indentation of C statements with respect to containing block.") ! 65: (defconst c-brace-imaginary-offset 0 ! 66: "*Imagined indentation of a C open brace that actually follows a statement.") ! 67: (defconst c-brace-offset 0 ! 68: "*Extra indentation for braces, compared with other text in same context.") ! 69: (defconst c-argdecl-indent 5 ! 70: "*Indentation level of declarations of C function arguments.") ! 71: (defconst c-label-offset -2 ! 72: "*Offset of C label lines and case statements relative to usual indentation.") ! 73: (defconst c-continued-statement-offset 2 ! 74: "*Extra indent for lines not starting new statements.") ! 75: (defconst c-continued-brace-offset 0 ! 76: "*Extra indent for substatements that start with open-braces. ! 77: This is in addition to c-continued-statement-offset.") ! 78: ! 79: (defconst c-auto-newline nil ! 80: "*Non-nil means automatically newline before and after braces, ! 81: and after colons and semicolons, inserted in C code.") ! 82: ! 83: (defconst c-tab-always-indent t ! 84: "*Non-nil means TAB in C mode should always reindent the current line, ! 85: regardless of where in the line point is when the TAB command is used.") ! 86: ! 87: (defun c-mode () ! 88: "Major mode for editing C code. ! 89: Expression and list commands understand all C brackets. ! 90: Tab indents for C code. ! 91: Comments are delimited with /* ... */. ! 92: Paragraphs are separated by blank lines only. ! 93: Delete converts tabs to spaces as it moves back. ! 94: \\{c-mode-map} ! 95: Variables controlling indentation style: ! 96: c-tab-always-indent ! 97: Non-nil means TAB in C mode should always reindent the current line, ! 98: regardless of where in the line point is when the TAB command is used. ! 99: c-auto-newline ! 100: Non-nil means automatically newline before and after braces, ! 101: and after colons and semicolons, inserted in C code. ! 102: c-indent-level ! 103: Indentation of C statements within surrounding block. ! 104: The surrounding block's indentation is the indentation ! 105: of the line on which the open-brace appears. ! 106: c-continued-statement-offset ! 107: Extra indentation given to a substatement, such as the ! 108: then-clause of an if or body of a while. ! 109: c-continued-brace-offset ! 110: Extra indentation given to a brace that starts a substatement. ! 111: This is in addition to c-continued-statement-offset. ! 112: c-brace-offset ! 113: Extra indentation for line if it starts with an open brace. ! 114: c-brace-imaginary-offset ! 115: An open brace following other text is treated as if it were ! 116: this far to the right of the start of its line. ! 117: c-argdecl-indent ! 118: Indentation level of declarations of C function arguments. ! 119: c-label-offset ! 120: Extra indentation for line that is a label, or case or default. ! 121: ! 122: Settings for K&R and BSD indentation styles are ! 123: c-indent-level 5 8 ! 124: c-continued-statement-offset 5 8 ! 125: c-brace-offset -5 -8 ! 126: c-argdecl-indent 0 8 ! 127: c-label-offset -5 -8 ! 128: ! 129: Turning on C mode calls the value of the variable c-mode-hook with no args, ! 130: if that value is non-nil." ! 131: (interactive) ! 132: (kill-all-local-variables) ! 133: (use-local-map c-mode-map) ! 134: (setq major-mode 'c-mode) ! 135: (setq mode-name "C") ! 136: (setq local-abbrev-table c-mode-abbrev-table) ! 137: (set-syntax-table c-mode-syntax-table) ! 138: (make-local-variable 'paragraph-start) ! 139: (setq paragraph-start (concat "^$\\|" page-delimiter)) ! 140: (make-local-variable 'paragraph-separate) ! 141: (setq paragraph-separate paragraph-start) ! 142: (make-local-variable 'paragraph-ignore-fill-prefix) ! 143: (setq paragraph-ignore-fill-prefix t) ! 144: (make-local-variable 'indent-line-function) ! 145: (setq indent-line-function 'c-indent-line) ! 146: (make-local-variable 'require-final-newline) ! 147: (setq require-final-newline t) ! 148: (make-local-variable 'comment-start) ! 149: (setq comment-start "/* ") ! 150: (make-local-variable 'comment-end) ! 151: (setq comment-end " */") ! 152: (make-local-variable 'comment-column) ! 153: (setq comment-column 32) ! 154: (make-local-variable 'comment-start-skip) ! 155: (setq comment-start-skip "/\\*+ *") ! 156: (make-local-variable 'comment-indent-hook) ! 157: (setq comment-indent-hook 'c-comment-indent) ! 158: (make-local-variable 'parse-sexp-ignore-comments) ! 159: (setq parse-sexp-ignore-comments t) ! 160: (run-hooks 'c-mode-hook)) ! 161: ! 162: ;; This is used by indent-for-comment ! 163: ;; to decide how much to indent a comment in C code ! 164: ;; based on its context. ! 165: (defun c-comment-indent () ! 166: (if (looking-at "^/\\*") ! 167: 0 ;Existing comment at bol stays there. ! 168: (save-excursion ! 169: (skip-chars-backward " \t") ! 170: (max (1+ (current-column)) ;Else indent at comment column ! 171: comment-column)))) ; except leave at least one space. ! 172: ! 173: (defun electric-c-brace (arg) ! 174: "Insert character and correct line's indentation." ! 175: (interactive "P") ! 176: (let (insertpos) ! 177: (if (and (not arg) ! 178: (eolp) ! 179: (or (save-excursion ! 180: (skip-chars-backward " \t") ! 181: (bolp)) ! 182: (if c-auto-newline (progn (c-indent-line) (newline) t) nil))) ! 183: (progn ! 184: (insert last-command-char) ! 185: (c-indent-line) ! 186: (if c-auto-newline ! 187: (progn ! 188: (newline) ! 189: ;; (newline) may have done auto-fill ! 190: (setq insertpos (- (point) 2)) ! 191: (c-indent-line))) ! 192: (save-excursion ! 193: (if insertpos (goto-char (1+ insertpos))) ! 194: (delete-char -1)))) ! 195: (if insertpos ! 196: (save-excursion ! 197: (goto-char insertpos) ! 198: (self-insert-command (prefix-numeric-value arg))) ! 199: (self-insert-command (prefix-numeric-value arg))))) ! 200: ! 201: (defun electric-c-semi (arg) ! 202: "Insert character and correct line's indentation." ! 203: (interactive "P") ! 204: (if c-auto-newline ! 205: (electric-c-terminator arg) ! 206: (self-insert-command (prefix-numeric-value arg)))) ! 207: ! 208: (defun electric-c-terminator (arg) ! 209: "Insert character and correct line's indentation." ! 210: (interactive "P") ! 211: (let (insertpos (end (point))) ! 212: (if (and (not arg) (eolp) ! 213: (not (save-excursion ! 214: (beginning-of-line) ! 215: (skip-chars-forward " \t") ! 216: (or (= (following-char) ?#) ! 217: ;; Colon is special only after a label, or case .... ! 218: ;; So quickly rule out most other uses of colon ! 219: ;; and do no indentation for them. ! 220: (and (eq last-command-char ?:) ! 221: (not (looking-at "case[ \t]")) ! 222: (save-excursion ! 223: (forward-word 1) ! 224: (skip-chars-forward " \t") ! 225: (< (point) end))) ! 226: (progn ! 227: (beginning-of-defun) ! 228: (let ((pps (parse-partial-sexp (point) end))) ! 229: (or (nth 3 pps) (nth 4 pps) (nth 5 pps)))))))) ! 230: (progn ! 231: (insert last-command-char) ! 232: (c-indent-line) ! 233: (and c-auto-newline ! 234: (not (c-inside-parens-p)) ! 235: (progn ! 236: (newline) ! 237: (setq insertpos (- (point) 2)) ! 238: (c-indent-line))) ! 239: (save-excursion ! 240: (if insertpos (goto-char (1+ insertpos))) ! 241: (delete-char -1)))) ! 242: (if insertpos ! 243: (save-excursion ! 244: (goto-char insertpos) ! 245: (self-insert-command (prefix-numeric-value arg))) ! 246: (self-insert-command (prefix-numeric-value arg))))) ! 247: ! 248: (defun c-inside-parens-p () ! 249: (condition-case () ! 250: (save-excursion ! 251: (save-restriction ! 252: (narrow-to-region (point) ! 253: (progn (beginning-of-defun) (point))) ! 254: (goto-char (point-max)) ! 255: (= (char-after (or (scan-lists (point) -1 1) (point-min))) ?\())) ! 256: (error nil))) ! 257: ! 258: (defun c-indent-command (&optional whole-exp) ! 259: "Indent current line as C code, or in some cases insert a tab character. ! 260: If c-tab-always-indent is non-nil (the default), always indent current line. ! 261: Otherwise, indent the current line only if point is at the left margin ! 262: or in the line's indentation; otherwise insert a tab. ! 263: ! 264: A numeric argument, regardless of its value, ! 265: means indent rigidly all the lines of the expression starting after point ! 266: so that this line becomes properly indented. ! 267: The relative indentation among the lines of the expression are preserved." ! 268: (interactive "P") ! 269: (if whole-exp ! 270: ;; If arg, always indent this line as C ! 271: ;; and shift remaining lines of expression the same amount. ! 272: (let ((shift-amt (c-indent-line)) ! 273: beg end) ! 274: (save-excursion ! 275: (if c-tab-always-indent ! 276: (beginning-of-line)) ! 277: (setq beg (point)) ! 278: (forward-sexp 1) ! 279: (setq end (point)) ! 280: (goto-char beg) ! 281: (forward-line 1) ! 282: (setq beg (point))) ! 283: (if (> end beg) ! 284: (indent-code-rigidly beg end shift-amt "#"))) ! 285: (if (and (not c-tab-always-indent) ! 286: (save-excursion ! 287: (skip-chars-backward " \t") ! 288: (not (bolp)))) ! 289: (insert-tab) ! 290: (c-indent-line)))) ! 291: ! 292: (defun c-indent-line () ! 293: "Indent current line as C code. ! 294: Return the amount the indentation changed by." ! 295: (let ((indent (calculate-c-indent nil)) ! 296: beg shift-amt ! 297: (case-fold-search nil) ! 298: (pos (- (point-max) (point)))) ! 299: (beginning-of-line) ! 300: (setq beg (point)) ! 301: (cond ((eq indent nil) ! 302: (setq indent (current-indentation))) ! 303: ((eq indent t) ! 304: (setq indent (calculate-c-indent-within-comment))) ! 305: ((looking-at "[ \t]*#") ! 306: (setq indent 0)) ! 307: (t ! 308: (skip-chars-forward " \t") ! 309: (if (listp indent) (setq indent (car indent))) ! 310: (cond ((or (looking-at "case[ \t]") ! 311: (and (looking-at "[A-Za-z]") ! 312: (save-excursion ! 313: (forward-sexp 1) ! 314: (looking-at ":")))) ! 315: (setq indent (max 1 (+ indent c-label-offset)))) ! 316: ((and (looking-at "else\\b") ! 317: (not (looking-at "else\\s_"))) ! 318: (setq indent (save-excursion ! 319: (c-backward-to-start-of-if) ! 320: (current-indentation)))) ! 321: ((= (following-char) ?}) ! 322: (setq indent (- indent c-indent-level))) ! 323: ((= (following-char) ?{) ! 324: (setq indent (+ indent c-brace-offset)))))) ! 325: (skip-chars-forward " \t") ! 326: (setq shift-amt (- indent (current-column))) ! 327: (if (zerop shift-amt) ! 328: (if (> (- (point-max) pos) (point)) ! 329: (goto-char (- (point-max) pos))) ! 330: (delete-region beg (point)) ! 331: (indent-to indent) ! 332: ;; If initial point was within line's indentation, ! 333: ;; position after the indentation. Else stay at same point in text. ! 334: (if (> (- (point-max) pos) (point)) ! 335: (goto-char (- (point-max) pos)))) ! 336: shift-amt)) ! 337: ! 338: (defun calculate-c-indent (&optional parse-start) ! 339: "Return appropriate indentation for current line as C code. ! 340: In usual case returns an integer: the column to indent to. ! 341: Returns nil if line starts inside a string, t if in a comment." ! 342: (save-excursion ! 343: (beginning-of-line) ! 344: (let ((indent-point (point)) ! 345: (case-fold-search nil) ! 346: state ! 347: containing-sexp) ! 348: (if parse-start ! 349: (goto-char parse-start) ! 350: (beginning-of-defun)) ! 351: (while (< (point) indent-point) ! 352: (setq parse-start (point)) ! 353: (setq state (parse-partial-sexp (point) indent-point 0)) ! 354: (setq containing-sexp (car (cdr state)))) ! 355: (cond ((or (nth 3 state) (nth 4 state)) ! 356: ;; return nil or t if should not change this line ! 357: (nth 4 state)) ! 358: ((null containing-sexp) ! 359: ;; Line is at top level. May be data or function definition, ! 360: ;; or may be function argument declaration. ! 361: ;; Indent like the previous top level line ! 362: ;; unless that ends in a closeparen without semicolon, ! 363: ;; in which case this line is the first argument decl. ! 364: (goto-char indent-point) ! 365: (skip-chars-forward " \t") ! 366: (if (= (following-char) ?{) ! 367: 0 ; Unless it starts a function body ! 368: (c-backward-to-noncomment (or parse-start (point-min))) ! 369: ;; Look at previous line that's at column 0 ! 370: ;; to determine whether we are in top-level decls ! 371: ;; or function's arg decls. Set basic-indent accordinglu. ! 372: (let ((basic-indent ! 373: (save-excursion ! 374: (re-search-backward "^[^ \^L\t\n#]" nil 'move) ! 375: (if (and (looking-at "\\sw\\|\\s_") ! 376: (looking-at "[^\"\n=(]*(") ! 377: (progn ! 378: (goto-char (1- (match-end 0))) ! 379: (forward-sexp 1) ! 380: (and (< (point) indent-point) ! 381: (not (memq (following-char) ! 382: '(?\, ?\;)))))) ! 383: c-argdecl-indent 0)))) ! 384: ;; Now add a little if this is a continuation line. ! 385: (+ basic-indent (if (or (bobp) ! 386: (memq (preceding-char) '(?\) ?\; ?\}))) ! 387: 0 c-continued-statement-offset))))) ! 388: ((/= (char-after containing-sexp) ?{) ! 389: ;; line is expression, not statement: ! 390: ;; indent to just after the surrounding open. ! 391: (goto-char (1+ containing-sexp)) ! 392: (current-column)) ! 393: (t ! 394: ;; Statement level. Is it a continuation or a new statement? ! 395: ;; Find previous non-comment character. ! 396: (goto-char indent-point) ! 397: (c-backward-to-noncomment containing-sexp) ! 398: ;; Back up over label lines, since they don't ! 399: ;; affect whether our line is a continuation. ! 400: (while (or (eq (preceding-char) ?\,) ! 401: (and (eq (preceding-char) ?:) ! 402: (or (eq (char-after (- (point) 2)) ?\') ! 403: (memq (char-syntax (char-after (- (point) 2))) ! 404: '(?w ?_))))) ! 405: (if (eq (preceding-char) ?\,) ! 406: (c-backward-to-start-of-continued-exp containing-sexp)) ! 407: (beginning-of-line) ! 408: (c-backward-to-noncomment containing-sexp)) ! 409: ;; Now we get the answer. ! 410: (if (not (memq (preceding-char) '(nil ?\, ?\; ?\} ?\{))) ! 411: ;; This line is continuation of preceding line's statement; ! 412: ;; indent c-continued-statement-offset more than the ! 413: ;; previous line of the statement. ! 414: (progn ! 415: (c-backward-to-start-of-continued-exp containing-sexp) ! 416: (+ c-continued-statement-offset (current-column) ! 417: (if (save-excursion (goto-char indent-point) ! 418: (skip-chars-forward " \t") ! 419: (eq (following-char) ?{)) ! 420: c-continued-brace-offset 0))) ! 421: ;; This line starts a new statement. ! 422: ;; Position following last unclosed open. ! 423: (goto-char containing-sexp) ! 424: ;; Is line first statement after an open-brace? ! 425: (or ! 426: ;; If no, find that first statement and indent like it. ! 427: (save-excursion ! 428: (forward-char 1) ! 429: (let ((colon-line-end 0)) ! 430: (while (progn (skip-chars-forward " \t\n") ! 431: (looking-at "#\\|/\\*\\|case[ \t\n].*:\\|[a-zA-Z0-9_$]*:")) ! 432: ;; Skip over comments and labels following openbrace. ! 433: (cond ((= (following-char) ?\#) ! 434: (forward-line 1)) ! 435: ((= (following-char) ?\/) ! 436: (forward-char 2) ! 437: (search-forward "*/" nil 'move)) ! 438: ;; case or label: ! 439: (t ! 440: (save-excursion (end-of-line) ! 441: (setq colon-line-end (point))) ! 442: (search-forward ":")))) ! 443: ;; The first following code counts ! 444: ;; if it is before the line we want to indent. ! 445: (and (< (point) indent-point) ! 446: (- ! 447: (if (> colon-line-end (point)) ! 448: (- (current-indentation) c-label-offset) ! 449: (current-column)) ! 450: (if (= (following-char) ?\{) c-brace-offset 0))))) ! 451: ;; If no previous statement, ! 452: ;; indent it relative to line brace is on. ! 453: ;; For open brace in column zero, don't let statement ! 454: ;; start there too. If c-indent-level is zero, ! 455: ;; use c-brace-offset + c-continued-statement-offset instead. ! 456: ;; For open-braces not the first thing in a line, ! 457: ;; add in c-brace-imaginary-offset. ! 458: (+ (if (and (bolp) (zerop c-indent-level)) ! 459: (+ c-brace-offset c-continued-statement-offset) ! 460: c-indent-level) ! 461: ;; Move back over whitespace before the openbrace. ! 462: ;; If openbrace is not first nonwhite thing on the line, ! 463: ;; add the c-brace-imaginary-offset. ! 464: (progn (skip-chars-backward " \t") ! 465: (if (bolp) 0 c-brace-imaginary-offset)) ! 466: ;; If the openbrace is preceded by a parenthesized exp, ! 467: ;; move to the beginning of that; ! 468: ;; possibly a different line ! 469: (progn ! 470: (if (eq (preceding-char) ?\)) ! 471: (forward-sexp -1)) ! 472: ;; Get initial indentation of the line we are on. ! 473: (current-indentation)))))))))) ! 474: ! 475: (defun calculate-c-indent-within-comment () ! 476: "Return the indentation amount for line, assuming that ! 477: the current line is to be regarded as part of a block comment." ! 478: (let (end star-start) ! 479: (save-excursion ! 480: (beginning-of-line) ! 481: (skip-chars-forward " \t") ! 482: (setq star-start (= (following-char) ?\*)) ! 483: (skip-chars-backward " \t\n") ! 484: (setq end (point)) ! 485: (beginning-of-line) ! 486: (skip-chars-forward " \t") ! 487: (and (re-search-forward "/\\*[ \t]*" end t) ! 488: star-start ! 489: (goto-char (1+ (match-beginning 0)))) ! 490: (current-column)))) ! 491: ! 492: ! 493: (defun c-backward-to-noncomment (lim) ! 494: (let (opoint stop) ! 495: (while (not stop) ! 496: (skip-chars-backward " \t\n\f" lim) ! 497: (setq opoint (point)) ! 498: (if (and (>= (point) (+ 2 lim)) ! 499: (save-excursion ! 500: (forward-char -2) ! 501: (looking-at "\\*/"))) ! 502: (search-backward "/*" lim 'move) ! 503: (setq stop (or (<= (point) lim) ! 504: (save-excursion ! 505: (beginning-of-line) ! 506: (skip-chars-forward " \t") ! 507: (not (looking-at "#"))))) ! 508: (or stop (beginning-of-line)))))) ! 509: ! 510: (defun c-backward-to-start-of-continued-exp (lim) ! 511: (if (= (preceding-char) ?\)) ! 512: (forward-sexp -1)) ! 513: (beginning-of-line) ! 514: (if (<= (point) lim) ! 515: (goto-char (1+ lim))) ! 516: (skip-chars-forward " \t")) ! 517: ! 518: (defun c-backward-to-start-of-if (&optional limit) ! 519: "Move to the start of the last ``unbalanced'' if." ! 520: (or limit (setq limit (save-excursion (beginning-of-defun) (point)))) ! 521: (let ((if-level 1) ! 522: (case-fold-search nil)) ! 523: (while (not (zerop if-level)) ! 524: (backward-sexp 1) ! 525: (cond ((looking-at "else\\b") ! 526: (setq if-level (1+ if-level))) ! 527: ((looking-at "if\\b") ! 528: (setq if-level (1- if-level))) ! 529: ((< (point) limit) ! 530: (setq if-level 0) ! 531: (goto-char limit)))))) ! 532: ! 533: ! 534: (defun mark-c-function () ! 535: "Put mark at end of C function, point at beginning." ! 536: (interactive) ! 537: (push-mark (point)) ! 538: (end-of-defun) ! 539: (push-mark (point)) ! 540: (beginning-of-defun) ! 541: (backward-paragraph)) ! 542: ! 543: (defun indent-c-exp () ! 544: "Indent each line of the C grouping following point." ! 545: (interactive) ! 546: (let ((indent-stack (list nil)) ! 547: (contain-stack (list (point))) ! 548: (case-fold-search nil) ! 549: restart outer-loop-done inner-loop-done state ostate ! 550: this-indent last-sexp ! 551: at-else at-brace ! 552: (opoint (point)) ! 553: (next-depth 0)) ! 554: (save-excursion ! 555: (forward-sexp 1)) ! 556: (save-excursion ! 557: (setq outer-loop-done nil) ! 558: (while (and (not (eobp)) (not outer-loop-done)) ! 559: (setq last-depth next-depth) ! 560: ;; Compute how depth changes over this line ! 561: ;; plus enough other lines to get to one that ! 562: ;; does not end inside a comment or string. ! 563: ;; Meanwhile, do appropriate indentation on comment lines. ! 564: (setq inner-loop-done nil) ! 565: (while (and (not inner-loop-done) ! 566: (not (and (eobp) (setq outer-loop-done t)))) ! 567: (setq ostate state) ! 568: (setq state (parse-partial-sexp (point) (progn (end-of-line) (point)) ! 569: nil nil state)) ! 570: (setq next-depth (car state)) ! 571: (if (and (car (cdr (cdr state))) ! 572: (>= (car (cdr (cdr state))) 0)) ! 573: (setq last-sexp (car (cdr (cdr state))))) ! 574: (if (or (nth 4 ostate)) ! 575: (c-indent-line)) ! 576: (if (or (nth 3 state)) ! 577: (forward-line 1) ! 578: (setq inner-loop-done t))) ! 579: (if (<= next-depth 0) ! 580: (setq outer-loop-done t)) ! 581: (if outer-loop-done ! 582: nil ! 583: ;; If this line had ..))) (((.. in it, pop out of the levels ! 584: ;; that ended anywhere in this line, even if the final depth ! 585: ;; doesn't indicate that they ended. ! 586: (while (> last-depth (nth 6 state)) ! 587: (setq indent-stack (cdr indent-stack) ! 588: contain-stack (cdr contain-stack) ! 589: last-depth (1- last-depth))) ! 590: (if (/= last-depth next-depth) ! 591: (setq last-sexp nil)) ! 592: ;; Add levels for any parens that were started in this line. ! 593: (while (< last-depth next-depth) ! 594: (setq indent-stack (cons nil indent-stack) ! 595: contain-stack (cons nil contain-stack) ! 596: last-depth (1+ last-depth))) ! 597: (if (null (car contain-stack)) ! 598: (setcar contain-stack (or (car (cdr state)) ! 599: (save-excursion (forward-sexp -1) ! 600: (point))))) ! 601: (forward-line 1) ! 602: (skip-chars-forward " \t") ! 603: (if (eolp) ! 604: nil ! 605: (if (and (car indent-stack) ! 606: (>= (car indent-stack) 0)) ! 607: ;; Line is on an existing nesting level. ! 608: ;; Lines inside parens are handled specially. ! 609: (if (/= (char-after (car contain-stack)) ?{) ! 610: (setq this-indent (car indent-stack)) ! 611: ;; Line is at statement level. ! 612: ;; Is it a new statement? Is it an else? ! 613: ;; Find last non-comment character before this line ! 614: (save-excursion ! 615: (setq at-else (looking-at "else\\W")) ! 616: (setq at-brace (= (following-char) ?{)) ! 617: (c-backward-to-noncomment opoint) ! 618: (if (not (memq (preceding-char) '(nil ?\, ?\; ?} ?: ?{))) ! 619: ;; Preceding line did not end in comma or semi; ! 620: ;; indent this line c-continued-statement-offset ! 621: ;; more than previous. ! 622: (progn ! 623: (c-backward-to-start-of-continued-exp (car contain-stack)) ! 624: (setq this-indent ! 625: (+ c-continued-statement-offset (current-column) ! 626: (if at-brace c-continued-brace-offset 0)))) ! 627: ;; Preceding line ended in comma or semi; ! 628: ;; use the standard indent for this level. ! 629: (if at-else ! 630: (progn (c-backward-to-start-of-if opoint) ! 631: (setq this-indent (current-indentation))) ! 632: (setq this-indent (car indent-stack)))))) ! 633: ;; Just started a new nesting level. ! 634: ;; Compute the standard indent for this level. ! 635: (let ((val (calculate-c-indent ! 636: (if (car indent-stack) ! 637: (- (car indent-stack)))))) ! 638: (setcar indent-stack ! 639: (setq this-indent val)))) ! 640: ;; Adjust line indentation according to its contents ! 641: (if (or (looking-at "case[ \t]") ! 642: (and (looking-at "[A-Za-z]") ! 643: (save-excursion ! 644: (forward-sexp 1) ! 645: (looking-at ":")))) ! 646: (setq this-indent (max 1 (+ this-indent c-label-offset)))) ! 647: (if (= (following-char) ?}) ! 648: (setq this-indent (- this-indent c-indent-level))) ! 649: (if (= (following-char) ?{) ! 650: (setq this-indent (+ this-indent c-brace-offset))) ! 651: ;; Put chosen indentation into effect. ! 652: (or (= (current-column) this-indent) ! 653: (= (following-char) ?\#) ! 654: (progn ! 655: (delete-region (point) (progn (beginning-of-line) (point))) ! 656: (indent-to this-indent))) ! 657: ;; Indent any comment following the text. ! 658: (or (looking-at comment-start-skip) ! 659: (if (re-search-forward comment-start-skip (save-excursion (end-of-line) (point)) t) ! 660: (progn (indent-for-comment) (beginning-of-line))))))))) ! 661: ; (message "Indenting C expression...done") ! 662: )
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.