;;; cc-engine.el --- core syntax guessing engine for CC mode
-;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2000 Free Software Foundation, Inc.
-;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 2000- Martin Stjernholm
+;; 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
(if (eq (char-before) ?\()
(setq last-begin (point))))
(goto-char last-begin)
- (setq last-begin (point)
- donep t)))
+ (setq donep t)))
(setq c-maybe-labelp nil)
;; see if we're in a literal. if not, then this bufpos may be
;; CASE 4: are we looking at a label? (But we handle
;; switch labels later.)
((and (looking-at c-label-key)
- (not (looking-at "default\\>"))))
+ (not (looking-at "default\\>"))
+ (not (and (c-major-mode-is 'pike-mode)
+ (save-excursion
+ ;; Not inside a Pike type declaration?
+ (and (c-safe (backward-up-list 1) t)
+ (eq (char-after) ?\()))))))
;; CASE 5: is this the first time we're checking?
(firstp (setq firstp nil
substmt-p (not (c-crosses-statement-barrier-p
(if (looking-at c-switch-label-key)
t
(goto-char here)
- nil))
- (looking-at c-label-key))))
+ nil)))))
;; CASE 8: ObjC or Java method def
((and c-method-key
(setq last-begin (c-in-method-def-p)))
(setq donep t))
- ;; CASE 9: nothing special
- (t (setq last-begin (point)))
+ ;; CASE 9: Normal token. At bob, we can end up at ws or a
+ ;; comment, and last-begin shouldn't be updated then.
+ ((not (looking-at "\\s \\|/[/*]"))
+ (setq last-begin (point)))
))))
(goto-char last-begin)
;; We always want to skip over the non-whitespace modifier
;; skip preprocessor directives
(when (and (eq (char-after) ?#)
(= (c-point 'boi) (point)))
- (while (eq (char-before (c-point 'eol)) ?\\)
- (forward-line 1))
+ (while (and (eq (char-before (c-point 'eol)) ?\\)
+ (= (forward-line 1) 0)))
(end-of-line))
)
(if lim (goto-char (min (point) lim)))))
;; Go to the first non-whitespace after the colon that starts a
;; multiple inheritance introduction. Optional LIM is the farthest
;; back we should search.
- (let ((lim (or lim (c-point 'bod)))
- (placeholder (progn
- (back-to-indentation)
- (point))))
+ (let* ((lim (or lim (c-point 'bod)))
+ (placeholder (progn
+ (back-to-indentation)
+ (point)))
+ (chr (char-after)))
(c-backward-syntactic-ws lim)
(while (and (> (point) lim)
- (memq (char-before) '(?, ?:))
+ (or (eq chr ?,)
+ (memq (char-before) '(?, ?:)))
(progn
(beginning-of-line)
(setq placeholder (point))
(skip-chars-forward " \t")
+ (setq chr (char-after))
(not (looking-at c-class-key))
))
(c-backward-syntactic-ws lim))
;; otherwise, we could be looking at a hanging member init
;; colon
(goto-char checkpoint)
+ (while (eq (char-before) ?,)
+ ;; this will catch member inits with multiple
+ ;; line arglists
+ (forward-char -1)
+ (c-backward-syntactic-ws (c-point 'bol))
+ (if (eq (char-before) ?\))
+ (c-backward-sexp 2)
+ (c-backward-sexp 1))
+ (c-backward-syntactic-ws))
(if (and (eq (char-before) ?:)
(progn
(forward-char -1)
((looking-at "\\<else\\>[ \t]+\\<if\\>") 3)
;; do, else, try, finally
((looking-at "\\<\\(do\\|else\\|try\\|finally\\)\\>") 1)
- ;; for, if, while, switch, catch, synchronized
+ ;; for, if, while, switch, catch, synchronized, foreach
(t 2))))
+(defun c-beginning-of-closest-statement (&optional lim)
+ ;; Go back to the closest preceding statement start.
+ (let ((start (point))
+ (label-re (concat c-label-key "\\|"
+ c-switch-label-key))
+ stmtbeg)
+ (if c-access-key
+ (setq label-re (concat label-re "\\|" c-access-key)))
+ (c-beginning-of-statement-1 lim)
+ (while (and (when (<= (point) start)
+ (setq stmtbeg (point)))
+ (cond
+ ((looking-at label-re)
+ ;; Skip a label.
+ (goto-char (match-end 0))
+ t)
+ ((looking-at c-conditional-key)
+ ;; Skip a conditional statement.
+ (c-safe (c-skip-conditional) t))
+ (t nil)))
+ (c-forward-syntactic-ws start))
+ (if stmtbeg
+ (goto-char stmtbeg))))
+
+(defun c-beginning-of-member-init-list (&optional limit)
+ ;; Goes to the beginning of a member init list (i.e. just after the
+ ;; ':') if inside one. Returns t in that case, nil otherwise.
+ (or limit
+ (setq limit (point-min)))
+ (skip-chars-forward " \t")
+ (if (eq (char-after) ?,)
+ (forward-char 1)
+ (c-backward-syntactic-ws limit))
+ (while (and (< limit (point))
+ (eq (char-before) ?,))
+ ;; this will catch member inits with multiple
+ ;; line arglists
+ (forward-char -1)
+ (c-backward-syntactic-ws)
+ (if (eq (char-before) ?\))
+ (c-backward-sexp 2)
+ (c-backward-sexp 1))
+ ;; Skip backwards over a fully::qualified::name.
+ (c-backward-syntactic-ws limit)
+ (while (and (eq (char-before) ?:)
+ (save-excursion
+ (forward-char -1)
+ (eq (char-before) ?:)))
+ (backward-char 2)
+ (c-backward-sexp 1))
+ ;; now continue checking
+ (c-backward-syntactic-ws limit))
+ (and (< limit (point))
+ (eq (char-before) ?:)))
+
(defun c-skip-case-statement-forward (state &optional lim)
;; skip forward over case/default bodies, with optional maximal
;; limit. if no next case body is found, nil is returned and point
(defun c-looking-at-special-brace-list (&optional lim)
;; If we're looking at the start of a pike-style list, ie `({ })',
- ;; `([ ])', `(< >)' etc, a cons of a cons its starting and ending
+ ;; `([ ])', `(< >)' etc, a cons of a cons of its starting and ending
;; positions and its entry in c-special-brace-lists is returned, nil
;; otherwise. The ending position is nil if the list is still open.
;; LIM is the limit for forward search. The point may either be at
(cons (list beg) type)))))
(error nil))))
+(defun c-looking-at-bos ()
+ ;; Returns nil if inside a statement or declaration.
+ (save-excursion
+ (c-backward-syntactic-ws)
+ (or (bobp)
+ (memq (char-before) '(?\; ?}))
+ (and (eq (char-before) ?{)
+ (not (and c-special-brace-lists
+ (progn (backward-char)
+ (c-looking-at-special-brace-list))))))))
+
(defun c-looking-at-inexpr-block (&optional lim)
;; Returns non-nil if we're looking at the beginning of a block
;; inside an expression. The value returned is actually a cons of
(setq res
(cond ((and block-follows
c-inexpr-class-key
- (looking-at c-inexpr-class-key))
+ (looking-at c-inexpr-class-key)
+ (or (not (looking-at c-class-key))
+ (let ((prev (point)))
+ (while (and (= (c-backward-token-1 1 t lim)
+ 0)
+ (>= (point) lim)
+ (eq (char-syntax (char-after))
+ ?w))
+ (setq prev (point)))
+ (goto-char prev)
+ (not (c-looking-at-bos)))))
(cons 'inexpr-class (point)))
((and c-inexpr-block-key
(looking-at c-inexpr-block-key))
(defun c-narrow-out-enclosing-class (state lim)
;; narrow the buffer so that the enclosing class is hidden
+ (setq state (c-whack-state (point) state))
(let (inclass-p)
(and state
(setq inclass-p (c-search-uplist-for-classkey state))
(case-fold-search nil)
(fullstate (c-parse-state))
(state fullstate)
- (in-method-intro-p (and (c-major-mode-is 'objc-mode)
- c-method-key
- (looking-at c-method-key)))
literal containing-sexp char-before-ip char-after-ip lim
syntax placeholder c-in-literal-cache inswitch-p
tmpsymbol keyword injava-inher special-brace-list
(skip-chars-forward " \t}")
(skip-chars-backward " \t")
(while (and state
- (not in-method-intro-p)
(not containing-sexp))
(setq containing-sexp (car state)
state (cdr state))
;; otherwise, ignore this element
(setq containing-sexp nil))
;; ignore the bufpos if its been narrowed out by the
- ;; containing class
- (if (<= containing-sexp (point-min))
+ ;; containing class or does not contain the indent point
+ (if (or (<= containing-sexp (point-min))
+ (>= containing-sexp indent-point))
(setq containing-sexp nil)))))
;; set the limit on the farthest back we need to search
;; CASE 2: in a C or C++ style comment.
((memq literal '(c c++))
(c-add-syntax literal (car (c-literal-limits lim))))
- ;; CASE 3: in a cpp preprocessor macro
- ((eq literal 'pound)
- (let ((boi (c-point 'boi))
- (macrostart (progn (c-beginning-of-macro lim) (point))))
- (setq tmpsymbol (if (= boi macrostart)
- 'cpp-macro
- 'cpp-macro-cont))
- (c-add-syntax tmpsymbol macrostart)))
- ;; CASE 4: in an objective-c method intro
- (in-method-intro-p
- (c-add-syntax 'objc-method-intro (c-point 'boi)))
+ ;; CASE 3: in a cpp preprocessor macro continuation.
+ ((and (eq literal 'pound)
+ (/= (save-excursion
+ (c-beginning-of-macro lim)
+ (setq placeholder (point)))
+ (c-point 'boi)))
+ (c-add-syntax 'cpp-macro-cont placeholder))
+ ;; CASE 4: In-expression statement.
+ ((and (or c-inexpr-class-key c-inexpr-block-key c-lambda-key)
+ (setq placeholder (c-looking-at-inexpr-block)))
+ (setq tmpsymbol (assq (car placeholder)
+ '((inexpr-class . class-open)
+ (inexpr-statement . block-open))))
+ (if tmpsymbol
+ ;; It's a statement block or an anonymous class.
+ (setq tmpsymbol (cdr tmpsymbol))
+ ;; It's a Pike lambda. Check whether we are between the
+ ;; lambda keyword and the argument list or at the defun
+ ;; opener.
+ (setq tmpsymbol (if (eq char-after-ip ?{)
+ 'inline-open
+ 'lambda-intro-cont)))
+ (goto-char (cdr placeholder))
+ (c-add-syntax tmpsymbol (c-point 'boi))
+ (c-add-syntax (car placeholder)))
;; CASE 5: Line is at top level.
((null containing-sexp)
(cond
(c-recognize-knr-p
(c-add-syntax 'knr-argdecl-intro (c-point 'boi))
(if inclass-p (c-add-class-syntax 'inclass inclass-p)))
- ;; CASE 5B.3: Nether region after a C++ or Java func
+ ;; CASE 5B.3: Inside a member init list.
+ ((c-beginning-of-member-init-list lim)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'member-init-cont (point)))
+ ;; CASE 5B.4: Nether region after a C++ or Java func
;; decl, which could include a `throws' declaration.
(t
(c-beginning-of-statement-1 lim)
)))
;; CASE 5C: inheritance line. could be first inheritance
;; line, or continuation of a multiple inheritance
- ((or (and c-baseclass-key (looking-at c-baseclass-key))
+ ((or (and c-baseclass-key
+ (progn
+ (when (eq char-after-ip ?,)
+ (skip-chars-forward " \t")
+ (forward-char))
+ (looking-at c-baseclass-key)))
(and (or (eq char-before-ip ?:)
;; watch out for scope operator
(save-excursion
(not (looking-at "[;{<,]"))))
(eq (char-after) ?,)))
(goto-char indent-point)
- (c-backward-syntactic-ws lim)
- (while (and (< lim (point))
- (eq (char-before) ?,))
- ;; this will catch member inits with multiple
- ;; line arglists
- (forward-char -1)
- (c-backward-syntactic-ws (c-point 'bol))
- (if (eq (char-before) ?\))
- (c-backward-sexp 2)
- (c-backward-sexp 1))
- ;; now continue checking
- (c-backward-syntactic-ws lim))
+ (c-beginning-of-member-init-list lim)
(cond
;; CASE 5D.1: hanging member init colon, but watch out
;; for bogus matches on access specifiers inside classes.
((and (save-excursion
- ;; There might be member inits on the first line too.
- (while (and (> (point) lim)
- (eq (char-before) ?,)
- (= (c-backward-token-1 2 t lim) 0)
- (eq (char-after) ?\()
- (= (c-backward-token-1 1 t lim) 0))
- (c-backward-syntactic-ws lim))
(setq placeholder (point))
(c-backward-token-1 1 t lim)
(and (eq (char-after) ?:)
(save-excursion
(goto-char placeholder)
(back-to-indentation)
- (and
- (if c-access-key (not (looking-at c-access-key)) t)
- (not (looking-at c-class-key))
- (if c-bitfield-key (not (looking-at c-bitfield-key)) t))
- ))
+ (or
+ (/= (car (save-excursion
+ (parse-partial-sexp (point) placeholder)))
+ 0)
+ (and
+ (if c-access-key (not (looking-at c-access-key)) t)
+ (not (looking-at c-class-key))
+ (if c-bitfield-key (not (looking-at c-bitfield-key)) t))
+ )))
(goto-char placeholder)
(c-forward-syntactic-ws)
(c-add-syntax 'member-init-cont (point))
(not (looking-at "typedef[ \t\n]+"))))
(goto-char placeholder)
(c-add-syntax 'knr-argdecl (c-point 'boi)))
- ;; CASE 5I: we are at the topmost level, make sure we skip
+ ;; CASE 5I: ObjC method definition.
+ ((and c-method-key
+ (looking-at c-method-key))
+ (c-add-syntax 'objc-method-intro (c-point 'boi)))
+ ;; CASE 5J: we are at the topmost level, make sure we skip
;; back past any access specifiers
((progn
(c-backward-syntactic-ws lim)
(t (c-add-class-syntax 'inclass inclass-p)))
))
))
- ;; CASE 5J: we are at an ObjC or Java method definition
+ ;; CASE 5K: we are at an ObjC or Java method definition
;; continuation line.
((and c-method-key
(progn
(beginning-of-line)
(looking-at c-method-key)))
(c-add-syntax 'objc-method-args-cont (point)))
- ;; CASE 5K: we are at the first argument of a template
+ ;; CASE 5L: we are at the first argument of a template
;; arglist that begins on the previous line.
((eq (char-before) ?<)
(c-beginning-of-statement-1 lim)
(c-forward-syntactic-ws)
(c-add-syntax 'template-args-cont (c-point 'boi)))
- ;; CASE 5L: we are at a topmost continuation line
+ ;; CASE 5M: we are at a topmost continuation line
(t
(c-beginning-of-statement-1 lim)
(c-forward-syntactic-ws)
(c-add-syntax 'topmost-intro-cont (c-point 'boi)))
)) ; end CASE 5
- ;; CASE 6: In-expression statement.
- ((and (or c-inexpr-class-key c-inexpr-block-key c-lambda-key)
- (setq placeholder (c-looking-at-inexpr-block)))
- (setq tmpsymbol (assq (car placeholder)
- '((inexpr-class . class-open)
- (inexpr-statement . block-open))))
- (if tmpsymbol
- ;; It's a statement block or an anonymous class.
- (setq tmpsymbol (cdr tmpsymbol))
- ;; It's a Pike lambda. Check whether we are between the
- ;; lambda keyword and the argument list or at the defun
- ;; opener.
- (setq tmpsymbol (if (eq char-after-ip ?{)
- 'inline-open
- 'lambda-intro-cont)))
- (goto-char (cdr placeholder))
- (c-add-syntax tmpsymbol (c-point 'boi))
- (c-add-syntax (car placeholder)))
+ ;; (CASE 6 has been removed.)
;; CASE 7: line is an expression, not a statement. Most
;; likely we are either in a function prototype or a function
;; call argument list
(not (eq char-before-ip ?,)))
(memq char-after-ip '(?\) ?\])))
(goto-char containing-sexp)
- (c-add-syntax 'arglist-close (c-point 'boi)))
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-close placeholder))
;; CASE 7B: Looking at the opening brace of an
;; in-expression block or brace list.
((eq char-after-ip ?{)
;; looking at a close paren or bracket.
((memq char-before-ip '(?\( ?\[))
(goto-char containing-sexp)
- (c-add-syntax 'arglist-intro (c-point 'boi)))
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-intro placeholder))
;; CASE 7D: we are inside a conditional test clause. treat
;; these things as statements
((save-excursion
(skip-chars-backward " \t([")
(<= (point) containing-sexp)))
(goto-char containing-sexp)
- (c-add-syntax 'arglist-cont-nonempty (c-point 'boi)))
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-cont-nonempty placeholder))
;; CASE 7G: we are looking at just a normal arglist
;; continuation line
(t (c-beginning-of-statement-1 containing-sexp)
(cond
;; CASE 9A: In the middle of a special brace list opener.
((and (consp special-brace-list)
+ (save-excursion
+ (goto-char containing-sexp)
+ (eq (char-after) ?\())
(eq char-after-ip (car (cdr special-brace-list))))
(goto-char (car (car special-brace-list)))
(skip-chars-backward " \t")
;; adjusts brace-list-open for brace lists as
;; top-level constructs, and brace lists inside
;; statements is a completely different context.
- (goto-char placeholder)
+ (goto-char indent-point)
+ (c-beginning-of-closest-statement)
(c-add-syntax 'statement-cont (c-point 'boi)))
- ;; CASE 10B.3: catch-all for unknown construct.
+ ;; CASE 10B.3: The body of a function declared inside a
+ ;; normal block. This can only occur in Pike.
+ ((and (c-major-mode-is 'pike-mode)
+ (progn
+ (goto-char indent-point)
+ (not (c-looking-at-bos))))
+ (c-beginning-of-closest-statement)
+ (c-add-syntax 'defun-open (c-point 'boi)))
+ ;; CASE 10B.4: catch-all for unknown construct.
(t
;; Can and should I add an extensibility hook here?
;; Something like c-recognize-hook so support for
;; been narrowed out by a class, then this is a
;; block-close
((and (not inenclosing-p)
- (c-most-enclosing-brace state))
+ (c-most-enclosing-brace state)
+ (or (not (c-major-mode-is 'pike-mode))
+ ;; In Pike it can be a defun-close of a
+ ;; function declared in a statement block. Let
+ ;; it through to be handled below.
+ (or (c-looking-at-bos)
+ (progn
+ (c-beginning-of-statement-1)
+ (looking-at c-conditional-key)))))
(c-add-syntax 'block-close relpos))
;; CASE 16D: find out whether we're closing a top-level
;; class or a defun
((and inswitch-p
(progn
(goto-char indent-point)
- (c-backward-syntactic-ws containing-sexp)
- (back-to-indentation)
+ (c-beginning-of-statement-1 containing-sexp)
(setq placeholder (point))
- (looking-at c-switch-label-key)))
+ (beginning-of-line)
+ (when (re-search-forward c-switch-label-key
+ (max placeholder (c-point 'eol)) t)
+ (setq placeholder (match-beginning 0)))))
(goto-char indent-point)
(skip-chars-forward " \t")
(if (eq (char-after) ?{)
(c-add-syntax 'statement-case-intro placeholder)))
;; CASE 17B: continued statement
((eq char-before-ip ?,)
+ (goto-char indent-point)
+ (c-beginning-of-closest-statement)
(c-add-syntax 'statement-cont (c-point 'boi)))
;; CASE 17C: a question/colon construct? But make sure
;; what came before was not a label, and what comes after
(skip-chars-forward " \t")
;; watch out for scope operator
(not (looking-at "::")))))
+ (goto-char indent-point)
+ (c-beginning-of-closest-statement)
(c-add-syntax 'statement-cont (c-point 'boi)))
;; CASE 17D: any old statement
((< (point) indent-point)
(if (and inswitch-p
(looking-at c-switch-label-key))
(progn
- (goto-char placeholder)
- (end-of-line)
- (c-forward-sexp -1)))
+ (goto-char (match-end 0))
+ (c-forward-syntactic-ws)))
(setq relpos (c-point 'boi))
(while (and (not done)
(<= safepos (point))
(c-looking-at-inexpr-block)))
(goto-char containing-sexp)
(back-to-indentation)
- (if (= containing-sexp (point))
- (c-add-syntax 'statement-block-intro (point))
- (goto-char (cdr placeholder))
- (c-add-syntax 'statement-block-intro (c-point 'boi))
- (c-add-syntax (car placeholder)))
+ (let ((block-intro (if (eq (car placeholder) 'inlambda)
+ 'defun-block-intro
+ 'statement-block-intro)))
+ (if (= containing-sexp (point))
+ (c-add-syntax block-intro (point))
+ (goto-char (cdr placeholder))
+ (c-add-syntax block-intro (c-point 'boi))
+ (c-add-syntax (car placeholder))))
(if (eq char-after-ip ?{)
(c-add-syntax 'block-open)))
;; CASE 17F: first statement in an inline, or first
(c-beginning-of-statement-1)
))
(c-add-syntax 'defun-block-intro (c-point 'boi)))
- ;; CASE 17G: first statement in a block
+ ;; CASE 17G: First statement in a function declared inside
+ ;; a normal block. This can only occur in Pike.
+ ((and (c-major-mode-is 'pike-mode)
+ (progn
+ (goto-char containing-sexp)
+ (and (not (c-looking-at-bos))
+ (progn
+ (c-beginning-of-statement-1)
+ (not (looking-at c-conditional-key))))))
+ (c-add-syntax 'defun-block-intro (c-point 'boi)))
+ ;; CASE 17H: first statement in a block
(t (goto-char containing-sexp)
(if (/= (point) (c-point 'boi))
(c-beginning-of-statement-1
(c-add-syntax 'block-open)))
))
)
-
;; now we need to look at any modifiers
(goto-char indent-point)
(skip-chars-forward " \t")
- ;; are we looking at a comment only line?
- (if (looking-at c-comment-start-regexp)
- (c-add-syntax 'comment-intro))
- ;; we might want to give additional offset to friends (in C++).
- (if (and (c-major-mode-is 'c++-mode)
- (looking-at c-C++-friend-key))
- (c-add-syntax 'friend))
+ (cond
+ ;; are we looking at a comment only line?
+ ((looking-at c-comment-start-regexp)
+ (c-add-syntax 'comment-intro))
+ ;; we might want to give additional offset to friends (in C++).
+ ((and (c-major-mode-is 'c++-mode)
+ (looking-at c-C++-friend-key))
+ (c-add-syntax 'friend))
+ ;; Start of a preprocessor directive?
+ ((and (eq literal 'pound)
+ (= (save-excursion
+ (c-beginning-of-macro lim)
+ (setq placeholder (point)))
+ (c-point 'boi)))
+ (c-add-syntax 'cpp-macro)))
;; return the syntax
syntax))))
(ding))
c-parsing-error)
-;; indent via syntactic language elements
-(defun c-indent-line (&optional syntax)
- ;; indent the current line as C/C++/ObjC code. Optional SYNTAX is the
- ;; syntactic information for the current line. Returns the amount of
- ;; indentation change (in columns).
- (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax)))
- (pos (- (point-max) (point)))
- (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context)))
- (shift-amt (- (current-indentation) indent)))
- (and c-echo-syntactic-information-p
- (not (c-echo-parsing-error))
- (message "syntax: %s, indent= %d" c-syntactic-context indent))
+(defun c-shift-line-indentation (shift-amt)
+ (let ((pos (- (point-max) (point)))
+ (col (current-indentation)))
(if (zerop shift-amt)
nil
(delete-region (c-point 'bol) (c-point 'boi))
(beginning-of-line)
- (indent-to indent))
+ (indent-to (+ col shift-amt)))
(if (< (point) (c-point 'boi))
(back-to-indentation)
;; If initial point was within line's indentation, position after
;; the indentation. Else stay at same point in text.
(if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
- )
- (run-hooks 'c-special-indent-hook)
+ (goto-char (- (point-max) pos))))))
+
+(defun c-indent-line (&optional syntax)
+ ;; Indent the current line as C/C++/ObjC code, if
+ ;; c-syntactic-indentation is non-nil. Optional SYNTAX is the
+ ;; syntactic information for the current line. Returns the amount
+ ;; of indentation change (in columns).
+ (let (shift-amt)
+ (if c-syntactic-indentation
+ (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax)))
+ (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context))))
+ (and c-echo-syntactic-information-p
+ (not (c-echo-parsing-error))
+ (message "syntax: %s, indent= %d" c-syntactic-context indent))
+ (setq shift-amt (- indent (current-indentation)))
+ (c-shift-line-indentation shift-amt)
+ (run-hooks 'c-special-indent-hook))
+ (let ((indent 0))
+ (save-excursion
+ (while (and (= (forward-line -1) 0)
+ (if (looking-at "\\s-*$")
+ t
+ (back-to-indentation)
+ (setq indent (current-indentation))
+ nil))))
+ (setq shift-amt (- indent (current-indentation)))
+ (c-shift-line-indentation shift-amt)))
shift-amt))
(defun c-show-syntactic-information (arg)