Annotation of GNUtools/emacs/lisp/c-mode.el, revision 1.1.1.1

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:   )

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.