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

unix.superglobalmegacorp.com

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