;;; cc-align.el --- custom indentation functions for CC Mode
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
-;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Boston, MA 02111-1307, USA.
(eval-when-compile
- (require 'cc-defs)
- (require 'cc-vars)
- (require 'cc-engine)
- (require 'cc-langs))
+ (let ((load-path
+ (if (and (boundp 'byte-compile-current-file)
+ (stringp byte-compile-current-file))
+ (cons (file-name-directory byte-compile-current-file)
+ load-path)
+ load-path)))
+ (load "cc-defs" nil t)))
+(require 'cc-engine)
\f
;; Standard indentation line-ups
+
(defun c-lineup-arglist (langelem)
- ;; lineup the current arglist line with the arglist appearing just
- ;; after the containing paren which starts the arglist.
+ "Line up the current argument line under the first argument.
+
+Works with: arglist-cont-nonempty."
(save-excursion
(let* ((containing-sexp
(save-excursion
(- (current-column) langelem-col))
(goto-char containing-sexp)
(or (eolp)
- (not (memq (char-after) '(?{ ?\( )))
+ (not (memq (char-after) '(?{ ?\( ?\[)))
(let ((eol (c-point 'eol))
(here (progn
(forward-char 1)
))))
(defun c-lineup-arglist-intro-after-paren (langelem)
- ;; lineup an arglist-intro line to just after the open paren
+ "Line up a line just after the open paren of the surrounding paren or
+brace block.
+
+Works with: defun-block-intro, brace-list-intro,
+statement-block-intro, statement-case-intro, arglist-intro."
(save-excursion
(let ((langelem-col (c-langelem-col langelem t))
(ce-curcol (save-excursion
(- ce-curcol langelem-col -1))))
(defun c-lineup-arglist-close-under-paren (langelem)
- ;; lineup an arglist-close line under the corresponding open paren
+ "Line up a closing paren line under the corresponding open paren.
+
+Works with: defun-close, class-close, inline-close, block-close,
+brace-list-close, arglist-close, extern-lang-close, namespace-close
+\(for most of these, a zero offset will normally produce the same
+result, though)."
(save-excursion
(let ((langelem-col (c-langelem-col langelem t))
(ce-curcol (save-excursion
(- ce-curcol langelem-col))))
(defun c-lineup-close-paren (langelem)
- ;; Indents the closing paren under its corresponding open paren if
- ;; the open paren is followed by code. If the open paren ends its
- ;; line, no indentation is added. E.g:
- ;;
- ;; main (int, main (
- ;; char ** int, char **
- ;; ) <-> ) <- c-lineup-close-paren
- ;;
- ;; Works with any type of paren.
+ "Line up the closing paren under its corresponding open paren if the
+open paren is followed by code. If the open paren ends its line, no
+indentation is added. E.g:
+
+main (int, main (
+ char ** int, char **
+ ) <-> ) <- c-lineup-close-paren
+
+Works with: defun-close, class-close, inline-close, block-close,
+brace-list-close, arglist-close, extern-lang-close, namespace-close."
(save-excursion
(condition-case nil
(let (opencol spec)
(if (eolp)
0
(- opencol (c-langelem-col langelem t))))
- (error 0))))
+ (error nil))))
(defun c-lineup-streamop (langelem)
- ;; lineup stream operators
+ "Line up C++ stream operators under each other.
+
+Works with: stream-op."
(save-excursion
(let ((langelem-col (c-langelem-col langelem)))
(re-search-forward "<<\\|>>" (c-point 'eol) 'move)
(- (current-column) langelem-col))))
(defun c-lineup-multi-inher (langelem)
- ;; line up multiple inheritance lines
+ "Line up the classes in C++ multiple inheritance clauses under each other.
+
+Works with: inher-cont."
(save-excursion
(let ((eol (c-point 'eol))
(here (point))
)))
(defun c-lineup-java-inher (langelem)
- ;; line up Java implements and extends continuations
+ "Line up Java implements and extends declarations.
+If class names follows on the same line as the implements/extends
+keyword, they are lined up under each other. Otherwise, they are
+indented by adding `c-basic-offset' to the column of the keyword.
+E.g:
+
+class Foo class Foo
+ extends extends Cyphr,
+ Bar <-> Bar <- c-lineup-java-inher
+ <--> c-basic-offset
+
+Works with: inher-cont."
(save-excursion
(let ((langelem-col (c-langelem-col langelem)))
(forward-word 1)
(if (looking-at "[ \t]*$")
- langelem-col
+ c-basic-offset
(c-forward-syntactic-ws)
(- (current-column) langelem-col)))))
(defun c-lineup-java-throws (langelem)
- ;; lineup func-decl-cont's in Java which are continuations of throws
- ;; declarations. If `throws' starts the previous line, line up to
- ;; just after that keyword. If not, lineup under the previous line.
+ "Line up Java throws declarations.
+If exception names follows on the same line as the throws keyword,
+they are lined up under each other. Otherwise, they are indented by
+adding `c-basic-offset' to the column of the throws keyword. The
+throws keyword itself is also indented by `c-basic-offset' from the
+function declaration start if it doesn't hang. E.g:
+
+int foo() int foo() throws Cyphr,
+ throws <-> Bar, <- c-lineup-java-throws
+ Bar <-> Vlod <- c-lineup-java-throws
+<--><--> c-basic-offset
+
+Works with: func-decl-cont."
(save-excursion
- (let ((iopl (c-point 'iopl))
- (langelem-col (c-langelem-col langelem t))
- (extra 0))
- (back-to-indentation)
- (cond
- ((looking-at "throws[ \t\n]")
- (goto-char (cdr langelem))
- (setq extra c-basic-offset))
- ((and (goto-char iopl)
- (looking-at "throws[ \t\n]"))
- (forward-word 1)
- (skip-chars-forward " \t")
- (if (eolp)
- (progn
- (back-to-indentation)
- (setq extra c-basic-offset))))
- (t (goto-char iopl)))
- (+ (- (current-column) langelem-col) extra))))
+ (let* ((lim (1- (c-point 'bol)))
+ (throws (catch 'done
+ (goto-char (cdr langelem))
+ (while (zerop (c-forward-token-1 1 t lim))
+ (if (looking-at "throws\\>[^_]")
+ (throw 'done t))))))
+ (if throws
+ (if (zerop (c-forward-token-1 1 nil (c-point 'eol)))
+ (- (current-column) (c-langelem-col langelem))
+ (back-to-indentation)
+ (+ (- (current-column) (c-langelem-col langelem))
+ c-basic-offset))
+ c-basic-offset))))
(defun c-indent-one-line-block (langelem)
- ;; Adds c-basic-offset to the indentation if the line is a one line
- ;; block, otherwise 0. E.g:
- ;;
- ;; if (n) if (n)
- ;; {m+=n; n=0;} <-> { <- c-indent-one-line-block
- ;; m+=n; n=0;
- ;; }
+ "Indent a one line block `c-basic-offset' extra.
+E.g:
+
+if (n > 0) if (n > 0)
+ {m+=n; n=0;} <-> { <- c-indent-one-line-block
+<--> c-basic-offset m+=n; n=0;
+ }
+
+The block may be surrounded by any kind of parenthesis characters.
+nil is returned if the line doesn't start with a one line block, which
+makes the function usable in list expressions.
+
+Work with: Almost all syntactic symbols, but most useful on *-open."
(save-excursion
- (let ((eol (progn (end-of-line) (point))))
- (beginning-of-line)
- (skip-chars-forward " \t")
- (if (and (eq (following-char) ?{)
+ (let ((eol (c-point 'eol)))
+ (back-to-indentation)
+ (if (and (eq (char-syntax (char-after)) ?\()
(c-safe (progn (c-forward-sexp) t))
- (<= (point) eol)
- (eq (preceding-char) ?}))
+ (<= (point) eol))
c-basic-offset
- 0))))
+ nil))))
-(defun c-lineup-C-comments (langelem)
- ;; line up C block comment continuation lines
+(defun c-indent-multi-line-block (langelem)
+ "Indent a multi line block `c-basic-offset' extra.
+E.g:
+
+int *foo[] = { int *foo[] = {
+ NULL, NULL,
+ {17}, <-> { <- c-indent-multi-line-block
+ 17
+ }
+ <--> c-basic-offset
+
+The block may be surrounded by any kind of parenthesis characters.
+nil is returned if the line doesn't start with a multi line block,
+which makes the function usable in list expressions.
+
+Work with: Almost all syntactic symbols, but most useful on *-open."
(save-excursion
- (let ((here (point))
- (stars (progn (back-to-indentation)
- (skip-chars-forward "*")))
- (langelem-col (c-langelem-col langelem)))
+ (let ((eol (c-point 'eol)))
(back-to-indentation)
- (if (not (re-search-forward "/\\([*]+\\)" (c-point 'eol) t))
- (progn
- (if (not (looking-at "[*]+"))
+ (if (and (eq (char-syntax (char-after)) ?\()
+ (or (not (c-safe (progn (c-forward-sexp) t)))
+ (> (point) eol)))
+ c-basic-offset
+ nil))))
+
+(defun c-lineup-C-comments (langelem)
+ "Line up C block comment continuation lines.
+Various heuristics are used to handle most of the common comment
+styles. Some examples:
+
+/* /** /* /* text /* /**
+ * text * text text text ** text ** text
+ */ */ */ */ */ */
+
+/*********************************************************************
+ * text
+ ********************************************************************/
+
+/*********************************************************************
+ Free form text comments:
+ In comments with a long delimiter line at the start, the indentation
+ is kept unchanged for lines that start with an empty comment line
+ prefix. The delimiter line is whatever matches the
+ `comment-start-skip' regexp.
+*********************************************************************/
+
+The variable `c-comment-prefix-regexp' is used to recognize the
+comment line prefix, e.g. the `*' that usually starts every line
+inside a comment.
+
+Works with: The `c' syntactic symbol."
+ (save-excursion
+ (let* ((here (point))
+ (prefixlen (progn (back-to-indentation)
+ (if (looking-at c-comment-prefix-regexp)
+ (- (match-end 0) (point))
+ 0)))
+ (starterlen (save-excursion
+ (goto-char (cdr langelem))
+ (looking-at comment-start-skip)
+ (- (save-excursion
+ (goto-char (match-end 0))
+ (skip-chars-backward " \t")
+ (point))
+ (or (match-end 1) (point))
+ 1))) ; Don't count the first '/'.
+ (langelem-col (save-excursion (c-langelem-col langelem))))
+ (if (and (> starterlen 10) (zerop prefixlen))
+ ;; The comment has a long starter and the line doesn't have
+ ;; a nonempty comment prefix. Treat it as free form text
+ ;; and don't change the indentation.
+ (- (current-column) langelem-col)
+ (forward-line -1)
+ (back-to-indentation)
+ (if (>= (cdr langelem) (point))
+ ;; On the second line in the comment.
+ (if (zerop prefixlen)
+ ;; No nonempty comment prefix. Align after comment
+ ;; starter.
(progn
- ;; we now have to figure out where this comment begins.
- (goto-char here)
- (back-to-indentation)
- (if (looking-at "[*]+/")
- (progn (goto-char (match-end 0))
- (forward-comment -1))
+ (goto-char (match-end 0))
+ (if (looking-at "\\([ \t]+\\).+$")
+ ;; Align with the text that hangs after the
+ ;; comment starter.
+ (goto-char (match-end 1)))
+ (- (current-column) langelem-col))
+ ;; How long is the comment starter? if greater than the
+ ;; length of the comment prefix, align left. if less
+ ;; than or equal, align right. this should also pick up
+ ;; Javadoc style comments.
+ (if (> starterlen prefixlen)
+ (progn
(goto-char (cdr langelem))
- (back-to-indentation))))
- (- (current-column) langelem-col))
- (if (zerop stars)
- (progn
- (skip-chars-forward " \t")
- (- (current-column) langelem-col))
- ;; how many stars on comment opening line? if greater than
- ;; on current line, align left. if less than or equal,
- ;; align right. this should also pick up Javadoc style
- ;; comments.
- (if (> (length (match-string 1)) stars)
- (progn
- (back-to-indentation)
- (- (current-column) -1 langelem-col))
- (- (current-column) stars langelem-col))
- )))))
+ (- (current-column) -1 langelem-col))
+ (goto-char (match-end 0))
+ (skip-chars-backward " \t")
+ (- (current-column) prefixlen langelem-col)))
+ ;; Not on the second line in the comment. If the previous
+ ;; line has a nonempty comment prefix, align with it.
+ ;; Otherwise, align with the previous nonempty line, but
+ ;; align the comment ender with the starter.
+ (when (or (not (looking-at c-comment-prefix-regexp))
+ (eq (match-beginning 0) (match-end 0)))
+ (goto-char here)
+ (back-to-indentation)
+ (if (looking-at (concat "\\(" c-comment-prefix-regexp "\\)\\*/"))
+ (goto-char (cdr langelem))
+ (while (and (zerop (forward-line -1))
+ (looking-at "^[ \t]*$")))
+ (back-to-indentation)
+ (if (< (point) (cdr langelem))
+ ;; Align with the comment starter rather than
+ ;; with the code before it.
+ (goto-char (cdr langelem)))))
+ (- (current-column) langelem-col))))))
(defun c-lineup-comment (langelem)
- ;; support old behavior for comment indentation. we look at
- ;; c-comment-only-line-offset to decide how to indent comment
- ;; only-lines
+ "Line up a comment start according to `c-comment-only-line-offset'.
+If the comment is lined up with a comment starter on the previous
+line, that alignment is preserved.
+
+Works with: comment-intro."
(save-excursion
(back-to-indentation)
;; this highly kludgiforous flag prevents the mapcar over
;; c-syntactic-context from entering an infinite loop
- (let ((recurse-prevention-flag (boundp 'recurse-prevention-flag)))
+ (let ((recurse-prevention-flag (boundp 'recurse-prevention-flag))
+ (col (current-column)))
(cond
- ;; CASE 1: preserve comment-column
(recurse-prevention-flag 0)
- ((= (current-column) comment-column)
+ ;; CASE 1: preserve aligned comments
+ ((save-excursion
+ (and (c-forward-comment -1)
+ (= col (current-column))))
;; we have to subtract out all other indentation
- (- comment-column (apply '+ (mapcar 'c-get-offset
- c-syntactic-context))))
+ (- col (apply '+ (mapcar 'c-get-offset
+ c-syntactic-context))))
;; indent as specified by c-comment-only-line-offset
((not (bolp))
(or (car-safe c-comment-only-line-offset)
))))
(defun c-lineup-runin-statements (langelem)
- ;; line up statements in coding standards which place the first
- ;; statement on the same line as the block opening brace.
+ "Line up statements when the first statement is on the same line as
+the block opening brace. E.g:
+
+int main()
+{ puts (\"Hello world!\");
+ return 0; <- c-lineup-runin-statements
+}
+
+If there is no statement after the opening brace to align with, nil is
+returned. This makes the function usable in list expressions.
+
+Works with: The `statement' syntactic symbol."
(if (eq (char-after (cdr langelem)) ?{)
(save-excursion
(let ((langelem-col (c-langelem-col langelem)))
(forward-char 1)
(skip-chars-forward " \t")
- (- (current-column) langelem-col)))
- 0))
+ (unless (eolp)
+ (- (current-column) langelem-col))))))
(defun c-lineup-math (langelem)
- ;; line up math statement-cont after the equals
+ "Line up the current line after the equal sign on the first line in
+the statement. If there isn't any, indent with `c-basic-offset'. If
+the current line contains an equal sign too, try to align it with the
+first one.
+
+Works with: statement-cont."
(save-excursion
(let ((equalp (save-excursion
(goto-char (c-point 'boi))
(- (current-column) equalp langelem-col))
)))
+(defun c-lineup-template-args (langelem)
+ "Line up template argument lines under the first argument.
+To allow this function to be used in a list expression, nil is
+returned if there's no template argument on the first line.
+
+Works with: template-args-cont."
+ (save-excursion
+ (c-with-syntax-table c++-template-syntax-table
+ (beginning-of-line)
+ (backward-up-list 1)
+ (if (and (eq (char-after) ?<)
+ (zerop (c-forward-token-1 1 nil (c-point 'eol))))
+ (- (current-column) (c-langelem-col langelem))))))
+
(defun c-lineup-ObjC-method-call (langelem)
- ;; Line up methods args as elisp-mode does with function args: go to
- ;; the position right after the message receiver, and if you are at
- ;; (eolp) indent the current line by a constant offset from the
- ;; opening bracket; otherwise we are looking at the first character
- ;; of the first method call argument, so lineup the current line
- ;; with it.
+ "Line up selector args as elisp-mode does with function args:
+Go to the position right after the message receiver, and if you are at
+the end of the line, indent the current line c-basic-offset columns
+from the opening bracket; otherwise you are looking at the first
+character of the first method call argument, so lineup the current
+line with it.
+
+Works with: objc-method-call-cont."
(save-excursion
(let* ((extra (save-excursion
(back-to-indentation)
(- target-col open-bracket-col extra))))
(defun c-lineup-ObjC-method-args (langelem)
- ;; Line up the colons that separate args. This is done trying to
- ;; align colons vertically.
+ "Line up the colons that separate args.
+The colon on the current line is aligned with the one on the first
+line.
+
+Works with: objc-method-args-cont."
(save-excursion
(let* ((here (c-point 'boi))
(curcol (progn (goto-char here) (current-column)))
c-basic-offset)))))
(defun c-lineup-ObjC-method-args-2 (langelem)
- ;; Line up the colons that separate args. This is done trying to
- ;; align the colon on the current line with the previous one.
+ "Line up the colons that separate args.
+The colon on the current line is aligned with the one on the previous
+line.
+
+Works with: objc-method-args-cont."
(save-excursion
(let* ((here (c-point 'boi))
(curcol (progn (goto-char here) (current-column)))
c-basic-offset)))))
(defun c-lineup-inexpr-block (langelem)
- ;; This function lines up the block for the various constructs that
- ;; uses a block inside an expression. For constructs matching
- ;; c-lambda-key and c-inexpr-block-key, indentation to the column of
- ;; the beginning of the match is added. For standalone statement
- ;; blocks, indentation to the column of the opening brace is added.
+ "Line up the block for constructs that use a block inside an expression,
+e.g. anonymous classes in Java and lambda functions in Pike. The body
+is aligned with the start of the header, e.g. with the \"new\" or
+\"lambda\" keyword. Returns nil if the block isn't part of such a
+construct.
+
+Works with: inlambda, inexpr-statement, inexpr-class."
(save-excursion
(back-to-indentation)
(let ((res (or (c-looking-at-inexpr-block)
(if (c-safe (backward-up-list 1)
(eq (char-after) ?{))
(c-looking-at-inexpr-block)))))
- (if (not res)
- 0
+ (when res
(goto-char (cdr res))
(- (current-column)
(progn
(back-to-indentation)
(current-column)))))))
-(defun c-lineup-dont-change (langelem)
- ;; Do not change the indentation of the current line
+(defun c-lineup-whitesmith-in-block (langelem)
+ "Line up lines inside a block in whitesmith style.
+It's done in a way that works both when the opening brace hangs and
+when it doesn't. E.g:
+
+something
+ { something {
+ foo; <-> foo; <- c-lineup-whitesmith-in-block
+ } }
+ <--> c-basic-offset
+
+In the first case the indentation is kept unchanged, in the
+second `c-basic-offset' is added.
+
+Works with: defun-close, defun-block-intro, block-close,
+brace-list-close, brace-list-intro, statement-block-intro, inclass,
+inextern-lang, innamespace."
(save-excursion
+ (goto-char (cdr langelem))
(back-to-indentation)
- (current-column)))
+ (if (eq (char-syntax (char-after)) ?\()
+ 0
+ c-basic-offset)))
+
+(defun c-lineup-dont-change (langelem)
+ "Do not change the indentation of the current line.
+Works with: Any syntactic symbol."
+ (save-excursion
+ (back-to-indentation)
+ (- (current-column) (c-langelem-col langelem))))
\f
(defun c-snug-do-while (syntax pos)
\f
;; Useful for c-hanging-semi&comma-criteria
+
(defun c-semi&comma-inside-parenlist ()
"Controls newline insertion after semicolons in parenthesis lists.
If a comma was inserted, no determination is made. If a semicolon was
;;; cc-cmds.el --- user level commands for CC Mode
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Softare Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
-;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-
-\f
(eval-when-compile
- (require 'cc-defs))
+ (let ((load-path
+ (if (and (boundp 'byte-compile-current-file)
+ (stringp byte-compile-current-file))
+ (cons (file-name-directory byte-compile-current-file)
+ load-path)
+ load-path)))
+ (load "cc-defs" nil t)))
+(require 'cc-engine)
+\f
(defun c-calculate-state (arg prevstate)
;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
;; arg is nil or zero, toggle the state. If arg is negative, turn
;; Do all appropriate clean ups
(let ((here (point))
(pos (- (point-max) (point)))
- mbeg mend)
+ mbeg mend tmp)
;; clean up empty defun braces
(if (and c-auto-newline
(memq 'empty-defun-braces c-cleanup-list)
;; make sure matching open brace isn't in a comment
(not (c-in-literal)))
(delete-region (point) (1- here)))
- ;; clean up brace-else-brace
- (if (and c-auto-newline
- (memq 'brace-else-brace c-cleanup-list)
- (eq last-command-char ?\{)
+ ;; clean up brace-else-brace and brace-elseif-brace
+ (when (and c-auto-newline
+ (eq last-command-char ?\{)
+ (not (c-in-literal)))
+ (cond
+ ((and (memq 'brace-else-brace c-cleanup-list)
(re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
(progn
(setq mbeg (match-beginning 0)
mend (match-end 0))
- (= mend here))
- (not (c-in-literal)))
- (progn
- (delete-region mbeg mend)
- (insert "} else {")))
+ (eq (match-end 0) here)))
+ (delete-region mbeg mend)
+ (insert "} else {"))
+ ((and (memq 'brace-elseif-brace c-cleanup-list)
+ (progn
+ (goto-char (1- here))
+ (setq mend (point))
+ (skip-chars-backward " \t\n")
+ (setq mbeg (point))
+ (eq (char-before) ?\)))
+ (= (c-backward-token-1 1 t) 0)
+ (eq (char-after) ?\()
+ (progn
+ (setq tmp (point))
+ (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*"
+ nil t))
+ (eq (match-end 0) tmp))
+ (delete-region mbeg mend)
+ (goto-char mbeg)
+ (insert " "))))
(goto-char (- (point-max) pos))
)
;; does a newline go after the brace?
appropriate; see the variable `c-cleanup-list'.
Also, the line is re-indented unless a numeric ARG is supplied, there
-are non-whitespace characters present on the line after the colon, or
-the colon is inserted inside a literal."
+are non-whitespace characters present on the line after the
+parenthesis, or the parenthesis is inserted inside a literal."
(interactive "*P")
(let (;; shut this up
(c-echo-syntactic-information-p nil))
(insert "} catch (")))
(goto-char (- (point-max) pos))
))
- (funcall old-blink-paren)))))
+ (if old-blink-paren
+ (funcall old-blink-paren))))))
\f
about finding the char with open-parenthesis syntax that starts the
defun."
(interactive "p")
+ (unless arg (setq arg 1))
(if (< arg 0)
(c-end-of-defun (- arg))
(while (> arg 0)
(cond
(bod (goto-char bod))
(prevbod (goto-char prevbod))
- (t (goto-char (c-point 'bod)))))
- (setq arg (1- arg))))
- (c-keep-region-active))
+ (t (goto-char (point-min))
+ (setq arg 0)))
+ (setq arg (1- arg))))
+ (c-keep-region-active)
+ (= arg 0)))
(defun c-end-of-defun (&optional arg)
"Move forward to next end of defun. With argument, do it that many times.
Negative argument -N means move back to Nth preceding end of defun.
+Returns t unless search stops due to beginning or end of buffer.
An end of a defun occurs right after the close-parenthesis that matches
the open-parenthesis that starts a defun; see `beginning-of-defun'."
(if (< arg 0)
(c-beginning-of-defun (- arg))
(while (> arg 0)
- ;; skip down into the next defun-block
- (while (and (c-safe (down-list 1) t)
- (not (eq (char-before) ?{)))
- (forward-char -1)
- (c-forward-sexp))
- (c-beginning-of-defun 1)
- (c-forward-sexp 1)
- (setq arg (1- arg)))
- (forward-line 1))
- (c-keep-region-active))
+ (let ((pos (point))
+ eol)
+ (while (and (c-safe (down-list 1) t)
+ (not (eq (char-before) ?{)))
+ ;; skip down into the next defun-block
+ (forward-char -1)
+ (c-forward-sexp))
+ (c-beginning-of-defun 1)
+ (setq eol (c-point 'eol))
+ (c-forward-sexp)
+ (if (< eol (point))
+ ;; Don't move to next line for one line defuns.
+ (forward-line 1))
+ (when (<= (point) pos)
+ (goto-char (point-max))
+ (setq arg 0))
+ (setq arg (1- arg))))
+ (c-keep-region-active)
+ (= arg 0)))
\f
(defun c-beginning-of-statement (&optional count lim sentence-flag)
(save-excursion
;; Find the comment next to point if we're not in one.
(if (> count 0)
- ;; Finding a comment backwards is a bit cumbersome
- ;; because `forward-comment' regards every newline as
- ;; a comment when searching backwards (Emacs 19.34).
- (while (and (progn (skip-chars-backward " \t")
- (setq range (point))
- (setq range (if (forward-comment -1)
- (cons (point) range)
- nil)))
- (= (char-after) ?\n)))
+ (setq range (if (c-forward-comment -1)
+ (cons (point)
+ (progn (c-forward-comment 1) (point)))))
(skip-chars-forward " \t\n")
(setq range (point))
- (setq range (if (forward-comment 1)
+ (setq range (if (c-forward-comment 1)
(cons range (point))
nil)))
(setq range (c-collect-line-comments range))))
(if range
(if (and sentence-flag
(/= (char-syntax (char-after (car range))) ?\"))
- (progn
+ (let* ((lit-type (c-literal-type range))
+ (beg (save-excursion
+ (goto-char (car range))
+ (looking-at (if (eq lit-type 'c)
+ comment-start-skip
+ (concat "\\("
+ c-comment-prefix-regexp
+ "\\)[ \t]*")))
+ (goto-char (match-end 0))
+ (point)))
+ (end (save-excursion
+ (goto-char (- (cdr range)
+ (if (eq lit-type 'c) 2 1)))
+ (point))))
;; move by sentence, but not past the limit of the literal
(save-restriction
- (narrow-to-region (save-excursion
- (goto-char (car range))
- (looking-at comment-start-skip)
- (goto-char (match-end 0))
- (point))
- (save-excursion
- (goto-char (cdr range))
- (if (save-excursion
- (goto-char (car range))
- (looking-at "/\\*"))
- (backward-char 2))
- (skip-chars-backward " \t\n")
- (point)))
- (c-safe (forward-sentence (if (> count 0) -1 1))))
+ (narrow-to-region beg end)
+ (c-safe (forward-sentence (if (< count 0) 1 -1)))
+ (if (and (memq lit-type '(c c++))
+ ;; Check if we stopped due to a comment
+ ;; prefix and not a sentence end.
+ (/= (point) beg)
+ (save-excursion
+ (beginning-of-line)
+ (looking-at (concat "[ \t]*\\("
+ c-comment-prefix-regexp
+ "\\)[ \t]*")))
+ (>= (point) (match-beginning 0))
+ (/= (match-beginning 1) (match-end 1))
+ (or (< (point) (match-end 0))
+ (and
+ (= (point) (match-end 0))
+ ;; The comment prefix may contain
+ ;; characters that is regarded as end
+ ;; of sentence.
+ (or (eolp)
+ (and
+ (save-excursion
+ (forward-paragraph -1)
+ (< (point) (match-beginning 0)))
+ (save-excursion
+ (beginning-of-line)
+ (or (not (re-search-backward
+ sentence-end
+ (c-point 'bopl)
+ t))
+ (< (match-end 0)
+ (c-point 'eol)))))))))
+ (setq count (+ count (if (< count 0) -1 1)))
+ (if (< count 0)
+ (progn
+ ;; In block comments, if there's only
+ ;; horizontal ws between the text and the
+ ;; comment ender, stop before it. Stop after
+ ;; the ender if there's either nothing or
+ ;; newlines between.
+ (when (and (eq lit-type 'c) (eq (point) end))
+ (widen)
+ (skip-chars-backward " \t")
+ (when (or (eq (point) end) (bolp))
+ (goto-char (cdr range)))))
+ (when (and (eq (point) beg) (looking-at "[ \t]*$"))
+ ;; Stop before instead of after the comment
+ ;; starter if nothing follows it.
+ (widen)
+ (goto-char (car range))))))
;; See if we should escape the literal.
(if (> count 0)
(if (< (point) here)
(goto-char (if (> count 0) (car range) (cdr range)))
(setq range nil))
;; Below we do approximately the same as
- ;; c-beginning-of-statement-1 and c-end-of-statement-1 and
+ ;; c-beginning-of-statement-1 and c-end-of-statement-1, and
;; perhaps they should be changed, but that'd likely break a
;; lot in cc-engine.
(goto-char here)
(if (> count 0)
- (if (condition-case nil
- ;; Stop before `{' and after `;', `{', `}' and
- ;; `};' when not followed by `}' or `)', but on
- ;; the other side of the syntactic ws. Also stop
- ;; before `}', but only to catch comments. Move
- ;; by sexps and move into parens.
- (catch 'done
- (let (last)
- (while t
- (setq last (point))
- (if (and (looking-at "[{}]")
- (/= here last))
- (throw 'done (= (char-after) ?{)))
- (c-backward-syntactic-ws)
- (cond ((bobp) ; Must handle bob specially.
- (if (= here last)
- (if (= last (point-min))
- (throw 'done t)
- (goto-char last)
- (throw 'done nil))
- (goto-char last)
- (throw 'done t)))
- ((progn (backward-char)
- (looking-at "[;{}]"))
- (if (or (= here last)
- (memq (char-after last) '(?\) ?})))
- (if (and (= (char-before) ?})
- (= (char-after) ?\;))
- (backward-char))
- (goto-char last)
- (throw 'done t)))
- ((= (char-syntax (char-after)) ?\")
- (forward-char)
- (c-backward-sexp))
- ))))
- (error
- (goto-char (point-min))
- t))
- (setq count (1- count)))
- (if (condition-case nil
- ;; Stop before `{' and `}', but on the other side of
- ;; the syntactic ws, and after `;', `}' and `};'.
- ;; Only stop before `{' if at top level or inside
- ;; braces, though. Also stop after `{', but only to
- ;; catch comments. Move by sexps and move into
- ;; parens.
+ (condition-case nil
+ ;; Stop before `{' and after `;', `{', `}' and `};'
+ ;; when not followed by `}' or `)', but on the other
+ ;; side of the syntactic ws. Move by sexps and move
+ ;; into parens. Also stop before `#' when it's first
+ ;; on a line.
+ (let ((comment-pos (not sentence-flag))
+ (large-enough (- (point-max)))
+ last last-below-line)
(catch 'done
- (let (last)
- (while t
- (setq last (point))
- (c-forward-syntactic-ws)
- (cond ((= (char-after) ?{)
+ (while t
+ (setq last (point))
+ (when (and (looking-at "{\\|^#") (/= here last))
+ (unless (and c-special-brace-lists
+ (eq (char-after) ?{)
+ (c-looking-at-special-brace-list))
+ (if (and (eq (char-after) ?#)
+ (numberp last-below-line)
+ (not (eq last-below-line here)))
+ (goto-char last-below-line))
+ (throw 'done t)))
+ (if comment-pos
+ (c-forward-comment large-enough)
+ (when (c-forward-comment -1)
+ ;; Record position of first comment.
+ (save-excursion
+ (c-forward-comment 1)
+ (setq comment-pos (point)))
+ (c-forward-comment large-enough)))
+ (unless last-below-line
+ (if (save-excursion
+ (re-search-forward "\\(^\\|[^\\]\\)$" last t))
+ (setq last-below-line last)))
+ (cond ((bobp) ; Must handle bob specially.
+ (if (= here last)
+ (throw 'done t)
+ (goto-char last)
+ (throw 'done t)))
+ ((progn (backward-char)
+ (looking-at "[;{}]"))
+ (if (and c-special-brace-lists
+ (eq (char-after) ?{)
+ (c-looking-at-special-brace-list))
+ (skip-syntax-backward "w_") ; Speedup only.
(if (or (= here last)
- (save-excursion
- (and (c-safe (progn (up-list -1) t))
- (/= (char-after) ?{))))
- (progn (forward-char)
- (throw 'done nil))
+ (memq (char-after last) '(?\) ?})))
+ (if (and (eq (char-before) ?})
+ (eq (char-after) ?\;))
+ (backward-char))
(goto-char last)
- (throw 'done t)))
- ((and (= (char-after) ?})
- (/= here last))
- (goto-char last)
- (throw 'done t))
- ((looking-at ";\\|};?")
- (goto-char (match-end 0))
- (throw 'done t))
- ((= (char-syntax (char-after)) ?\")
- (c-forward-sexp))
- (t
- (forward-char))
- ))))
- (error
- (goto-char (point-max))
- t))
- (setq count (1+ count)))))
+ (throw 'done t))))
+ ((= (char-syntax (char-after)) ?\")
+ (forward-char)
+ (c-backward-sexp))
+ (t (skip-syntax-backward "w_")) ; Speedup only.
+ )))
+ (if (and (numberp comment-pos)
+ (< (point) comment-pos))
+ ;; We jumped over a comment that should be investigated.
+ (goto-char comment-pos)
+ (setq count (1- count))))
+ (error
+ (goto-char (point-min))
+ (setq count 0)))
+ (condition-case nil
+ ;; Stop before `{', `}', and `#' when it's first on a
+ ;; line, but on the other side of the syntactic ws, and
+ ;; after `;', `}' and `};'. Only stop before `{' if at
+ ;; top level or inside braces, though. Move by sexps
+ ;; and move into parens. Also stop at eol of lines
+ ;; starting with `#'.
+ (let ((comment-pos (not sentence-flag))
+ (large-enough (point-max))
+ last)
+ (catch 'done
+ (while t
+ (setq last (point))
+ (if comment-pos
+ (c-forward-comment large-enough)
+ (if (progn
+ (skip-chars-forward " \t\n\r\f")
+ ;; Record position of first comment.
+ (setq comment-pos (point))
+ (c-forward-comment 1))
+ (c-forward-comment large-enough)
+ (setq comment-pos nil)))
+ (cond ((and (eq (char-after) ?{)
+ (not (and c-special-brace-lists
+ (c-looking-at-special-brace-list)))
+ (/= here last)
+ (save-excursion
+ (or (not (c-safe (up-list -1) t))
+ (= (char-after) ?{))))
+ (goto-char last)
+ (throw 'done t))
+ ((and c-special-brace-lists
+ (eq (char-after) ?})
+ (save-excursion
+ (and (c-safe (up-list -1) t)
+ (c-looking-at-special-brace-list))))
+ (forward-char 1)
+ (skip-syntax-forward "w_")) ; Speedup only.
+ ((and (eq (char-after) ?})
+ (/= here last))
+ (goto-char last)
+ (throw 'done t))
+ ((looking-at "^#")
+ (if (= here last)
+ (or (re-search-forward "\\(^\\|[^\\]\\)$" nil t)
+ (goto-char (point-max)))
+ (goto-char last))
+ (throw 'done t))
+ ((looking-at ";\\|};?")
+ (goto-char (match-end 0))
+ (throw 'done t))
+ ((= (char-syntax (char-after)) ?\")
+ (c-forward-sexp))
+ (t
+ (forward-char 1)
+ (skip-syntax-forward "w_")) ; Speedup only.
+ )))
+ (if (and (numberp comment-pos)
+ (> (point) comment-pos))
+ ;; We jumped over a comment that should be investigated.
+ (goto-char comment-pos)
+ (setq count (1+ count))))
+ (error
+ (goto-char (point-max))
+ (setq count 0)))
+ ))
;; If we haven't moved we're near a buffer limit.
- (when (= (point) here)
+ (when (and (not (zerop count)) (= (point) here))
(goto-char (if (> count 0) (point-min) (point-max)))
(setq count 0)))
;; its possible we've been left up-buf of lim
(cons c-comment-only-line-offset
c-comment-only-line-offset))))
(apply '+ (mapcar 'c-get-offset syntax)))))
- ;; CASE 4: use comment-column if previous line is a
- ;; comment-only line indented to the left of comment-column
+ ;; CASE 4: If previous line is a comment-only line, use its
+ ;; indentation if it's greater than comment-column. Leave at
+ ;; least one space between the comment and the last nonblank
+ ;; character in any case.
((save-excursion
(beginning-of-line)
(and (not (bobp))
(skip-chars-forward " \t")
(prog1
(looking-at c-comment-start-regexp)
- (setq placeholder (point))))
- (goto-char placeholder)
- (if (< (current-column) comment-column)
- comment-column
- (current-column)))
+ (setq placeholder (current-column))))
+ (goto-char opoint)
+ (skip-chars-backward " \t")
+ (max (if (bolp) 0 (1+ (current-column)))
+ placeholder
+ comment-column))
;; CASE 5: If comment-column is 0, and nothing but space
;; before the comment, align it at 0 rather than 1.
((progn
)))))
\f
-;; for proposed new variable comment-line-break-function
-(defun c-comment-line-break-function (&optional soft)
- ;; we currently don't do anything with soft line breaks
- (let ((literal (c-in-literal))
- at-comment-col)
- (cond
- ((eq literal 'string)
- (insert ?\n))
- ((or (not c-comment-continuation-stars)
- (not literal))
- (indent-new-comment-line soft))
- (t (let ((here (point))
- (leader c-comment-continuation-stars))
- (back-to-indentation)
- ;; comment could be hanging
- (if (not (c-in-literal))
- (progn
- (forward-line 1)
- (forward-comment -1)
- (setq at-comment-col (= (current-column) comment-column))))
- ;; are we looking at a block or lines style comment?
- (if (and (looking-at (concat "\\(" c-comment-start-regexp
- "\\)[ \t]+"))
- (string-equal (match-string 1) "//"))
- ;; line style
- (setq leader (match-string 0)))
- (goto-char here)
- (delete-region (progn (skip-chars-backward " \t") (point))
- (progn (skip-chars-forward " \t") (point)))
- (newline)
- ;; to avoid having an anchored comment that c-indent-line will
- ;; trip up on
- (insert " " leader)
- (if at-comment-col
- (indent-for-comment))
- (c-indent-line))))))
-
-;; advice for indent-new-comment-line for older Emacsen
-(or (boundp 'comment-line-break-function)
- (defadvice indent-new-comment-line (around c-line-break-advice
- activate preactivate)
- "Calls c-comment-line-break-function if in a comment in CC Mode."
- (if (or (not c-buffer-is-cc-mode)
- (not (c-in-literal))
- (not c-comment-continuation-stars))
- ad-do-it
- (c-comment-line-break-function (ad-get-arg 0)))))
-
;; used by outline-minor-mode
(defun c-outline-level ()
- ;; This so that `current-column' DTRT in otherwise-hidden text.
- (let (buffer-invisibility-spec)
- (save-excursion
- (skip-chars-forward "\t ")
- (current-column))))
+ (save-excursion
+ (skip-chars-forward "\t ")
+ (current-column)))
\f
(defun c-up-conditional (count)
"Move back to the containing preprocessor conditional, leaving mark behind.
A prefix argument acts as a repeat count. With a negative argument,
move forward to the end of the containing preprocessor conditional.
-When going backwards, `#elif' is treated like `#else' followed by
-`#if'. When going forwards, `#elif' is ignored."
+
+`#elif' is treated like `#else' followed by `#if', so the function
+stops at them when going backward, but not when going forward."
+ (interactive "p")
+ (c-forward-conditional (- count) -1)
+ (c-keep-region-active))
+
+(defun c-up-conditional-with-else (count)
+ "Move back to the containing preprocessor conditional, including `#else'.
+Just like `c-up-conditional', except it also stops at `#else'
+directives."
+ (interactive "p")
+ (c-forward-conditional (- count) -1 t)
+ (c-keep-region-active))
+
+(defun c-down-conditional (count)
+ "Move forward into the next preprocessor conditional, leaving mark behind.
+A prefix argument acts as a repeat count. With a negative argument,
+move backward into the previous preprocessor conditional.
+
+`#elif' is treated like `#else' followed by `#if', so the function
+stops at them when going forward, but not when going backward."
(interactive "p")
- (c-forward-conditional (- count) t)
+ (c-forward-conditional count 1)
(c-keep-region-active))
-(defun c-backward-conditional (count &optional up-flag)
+(defun c-down-conditional-with-else (count)
+ "Move forward into the next preprocessor conditional, including `#else'.
+Just like `c-down-conditional', except it also stops at `#else'
+directives."
+ (interactive "p")
+ (c-forward-conditional count 1 t)
+ (c-keep-region-active))
+
+(defun c-backward-conditional (count &optional target-depth with-else)
"Move back across a preprocessor conditional, leaving mark behind.
A prefix argument acts as a repeat count. With a negative argument,
move forward across a preprocessor conditional."
(interactive "p")
- (c-forward-conditional (- count) up-flag)
+ (c-forward-conditional (- count) target-depth with-else)
(c-keep-region-active))
-(defun c-forward-conditional (count &optional up-flag)
+(defun c-forward-conditional (count &optional target-depth with-else)
"Move forward across a preprocessor conditional, leaving mark behind.
A prefix argument acts as a repeat count. With a negative argument,
-move backward across a preprocessor conditional."
+move backward across a preprocessor conditional.
+
+`#elif' is treated like `#else' followed by `#if', except that the
+nesting level isn't changed when tracking subconditionals.
+
+The optional argument TARGET-DEPTH specifies the wanted nesting depth
+after each scan. I.e. if TARGET-DEPTH is -1, the function will move
+out of the enclosing conditional. A non-integer non-nil TARGET-DEPTH
+counts as -1.
+
+If the optional argument WITH-ELSE is non-nil, `#else' directives are
+treated as conditional clause limits. Normally they are ignored."
(interactive "p")
(let* ((forward (> count 0))
(increment (if forward -1 1))
(search-function (if forward 're-search-forward 're-search-backward))
(new))
+ (unless (integerp target-depth)
+ (setq target-depth (if target-depth -1 0)))
(save-excursion
(while (/= count 0)
- (let ((depth (if up-flag 0 -1)) found)
+ (let ((depth 0)
+ ;; subdepth is the depth in "uninteresting" subtrees,
+ ;; i.e. those that takes us farther from the target
+ ;; depth instead of closer.
+ (subdepth 0)
+ found)
(save-excursion
;; Find the "next" significant line in the proper direction.
(while (and (not found)
;; precedes it. This is faster on account of
;; the fastmap feature of the regexp matcher.
(funcall search-function
- "#[ \t]*\\(if\\|elif\\|endif\\)"
+ "#[ \t]*\\(if\\|elif\\|endif\\|else\\)"
nil t))
(beginning-of-line)
;; Now verify it is really a preproc line.
- (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
- (let ((prev depth))
- ;; Update depth according to what we found.
- (beginning-of-line)
- (cond ((looking-at "[ \t]*#[ \t]*endif")
- (setq depth (+ depth increment)))
- ((looking-at "[ \t]*#[ \t]*elif")
- (if (and forward (= depth 0))
- (setq found (point))))
- (t (setq depth (- depth increment))))
- ;; If we are trying to move across, and we find an
- ;; end before we find a beginning, get an error.
- (if (and (< prev 0) (< depth prev))
- (error (if forward
- "No following conditional at this level"
- "No previous conditional at this level")))
+ (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\|else\\)")
+ (let (dchange (directive (match-string 1)))
+ (cond ((string= directive "if")
+ (setq dchange (- increment)))
+ ((string= directive "endif")
+ (setq dchange increment))
+ ((= subdepth 0)
+ ;; When we're not in an "uninteresting"
+ ;; subtree, we might want to act on "elif"
+ ;; and "else" too.
+ (if (cond (with-else
+ ;; Always move toward the target depth.
+ (setq dchange
+ (if (> target-depth 0) 1 -1)))
+ ((string= directive "elif")
+ (setq dchange (- increment))))
+ ;; Ignore the change if it'd take us
+ ;; into an "uninteresting" subtree.
+ (if (eq (> dchange 0) (<= target-depth 0))
+ (setq dchange nil)))))
+ (when dchange
+ (when (or (/= subdepth 0)
+ (eq (> dchange 0) (<= target-depth 0)))
+ (setq subdepth (+ subdepth dchange)))
+ (setq depth (+ depth dchange))
+ ;; If we are trying to move across, and we find an
+ ;; end before we find a beginning, get an error.
+ (if (and (< depth target-depth) (< dchange 0))
+ (error (if forward
+ "No following conditional at this level"
+ "No previous conditional at this level"))))
;; When searching forward, start from next line so
;; that we don't find the same line again.
(if forward (forward-line 1))
- ;; If this line exits a level of conditional, exit
- ;; inner loop.
- (if (< depth 0)
+ ;; We found something if we've arrived at the
+ ;; target depth.
+ (if (and dchange (= depth target-depth))
(setq found (point))))
;; else
- (if forward (forward-line 1))
- )))
+ (if forward (forward-line 1)))))
(or found
(error "No containing preprocessor conditional"))
(goto-char (setq new found)))
"Indent each line in balanced expression following point.
Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
(interactive "*P")
- (let ((here (point))
+ (let ((here (point-marker))
end progress-p)
+ (set-marker-insertion-type here t)
(unwind-protect
(let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
(start (progn
(set-marker end nil))
(and progress-p
(c-progress-fini 'c-indent-exp))
- (goto-char here))))
+ (goto-char here)
+ (set-marker here nil))))
(defun c-indent-defun ()
"Re-indents the current top-level function def, struct or class declaration."
(setq sexpbeg (point))))
(if (and sexpbeg (< sexpbeg fence))
(setq sexpbeg fence)))
- ;; check to see if the next line starts a
- ;; comment-only line
- (save-excursion
- (forward-line 1)
- (skip-chars-forward " \t")
- (if (looking-at c-comment-start-regexp)
- (setq sexpbeg (c-point 'bol))))
+ ;; Since we move by sexps we might have missed
+ ;; comment-only lines.
+ (if sexpbeg
+ (save-excursion
+ (while (progn
+ (forward-line 1)
+ (skip-chars-forward " \t")
+ (< (point) sexpbeg))
+ (if (looking-at c-comment-start-regexp)
+ (setq sexpbeg (c-point 'bol))))))
;; If that sexp ends within the region, indent it all at
;; once, fast.
(condition-case nil
(delete-region (1+ (point))
(progn (skip-chars-backward " \t") (point)))))))
+
\f
+;;; Line breaking and paragraph filling.
+
+;; The filling code is based on a simple theory; leave the intricacies
+;; of the text handling to the currently active mode for that
+;; (e.g. adaptive-fill-mode or filladapt-mode) and do as little as
+;; possible to make them work correctly wrt the comment and string
+;; separators, one-line paragraphs etc. Unfortunately, when it comes
+;; to it, there's quite a lot of special cases to handle which makes
+;; the code anything but simple. The intention is that it will work
+;; with any well-written text filling package that preserves a fill
+;; prefix.
+;;
+;; We temporarily mask comment starters and enders as necessary for
+;; the filling code to do its job on a seemingly normal text block.
+;; We do _not_ mask the fill prefix, so it's up to the filling code to
+;; preserve it correctly (especially important when filling C++ style
+;; line comments). By default, we set up and use adaptive-fill-mode,
+;; which is standard in all supported Emacs flavors.
+
+(defun c-guess-fill-prefix (lit-limits lit-type)
+ ;; Determine the appropriate comment fill prefix for a block or line
+ ;; comment. Return a cons of the prefix string and the column where
+ ;; it ends. If fill-prefix is set, it'll override. Note that this
+ ;; function also uses the value of point in some heuristics.
+ (let* ((here (point))
+ (prefix-regexp (concat "[ \t]*\\("
+ c-comment-prefix-regexp
+ "\\)[ \t]*"))
+ (comment-start-regexp (if (eq lit-type 'c++)
+ prefix-regexp
+ comment-start-skip))
+ prefix-line comment-prefix res)
+ (cond
+ (fill-prefix
+ (setq res (cons fill-prefix
+ ;; Ugly way of getting the column after the fill
+ ;; prefix; it'd be nice with a current-column
+ ;; that works on strings..
+ (let ((buffer-modified (buffer-modified-p))
+ (buffer-undo-list t)
+ (start (point)))
+ (unwind-protect
+ (progn
+ (insert ?\n fill-prefix)
+ (current-column))
+ (delete-region start (point))
+ (set-buffer-modified-p buffer-modified))))))
+ ((eq lit-type 'c++)
+ (save-excursion
+ ;; Set fallback for comment-prefix if none is found.
+ (setq comment-prefix "// ")
+ (beginning-of-line)
+ (if (> (point) (car lit-limits))
+ ;; The current line is not the comment starter, so the
+ ;; comment has more than one line, and it can therefore be
+ ;; used to find the comment fill prefix.
+ (setq prefix-line (point))
+ (goto-char (car lit-limits))
+ (if (and (= (forward-line 1) 0)
+ (< (point) (cdr lit-limits)))
+ ;; The line after the comment starter is inside the
+ ;; comment, so we can use it.
+ (setq prefix-line (point))
+ ;; The comment is only one line. Take the comment prefix
+ ;; from it and keep the indentation.
+ (goto-char (car lit-limits))
+ (if (looking-at prefix-regexp)
+ (goto-char (match-end 0))
+ (forward-char 2)
+ (skip-chars-forward " \t"))
+ (setq res
+ (if (eq (c-point 'boi) (car lit-limits))
+ ;; There is only whitespace before the comment
+ ;; starter; take the prefix straight from this
+ ;; line.
+ (cons (buffer-substring-no-properties
+ (c-point 'bol) (point))
+ (current-column))
+ ;; There is code before the comment starter, so we
+ ;; have to temporarily insert and indent a new
+ ;; line to get the right space/tab mix in the
+ ;; indentation.
+ (let ((buffer-modified (buffer-modified-p))
+ (buffer-undo-list t)
+ (prefix-len (- (point) (car lit-limits)))
+ tmp)
+ (unwind-protect
+ (progn
+ (goto-char (car lit-limits))
+ (indent-to (prog1 (current-column)
+ (insert ?\n)))
+ (setq tmp (point))
+ (forward-char prefix-len)
+ (cons (buffer-substring-no-properties
+ (c-point 'bol) (point))
+ (current-column)))
+ (delete-region (car lit-limits) tmp)
+ (set-buffer-modified-p buffer-modified))))
+ )))))
+ (t
+ (save-excursion
+ (beginning-of-line)
+ (if (and (> (point) (car lit-limits))
+ (not (and (looking-at "[ \t]*\\*/")
+ (eq (cdr lit-limits) (match-end 0)))))
+ ;; The current line is not the comment starter and
+ ;; contains more than just the ender, so it's good enough
+ ;; to be used for the comment fill prefix.
+ (setq prefix-line (point))
+ (goto-char (car lit-limits))
+ (if (or (/= (forward-line 1) 0)
+ (>= (point) (cdr lit-limits))
+ (and (looking-at "[ \t]*\\*/")
+ (eq (cdr lit-limits) (match-end 0)))
+ (and (looking-at prefix-regexp)
+ (<= (1- (cdr lit-limits)) (match-end 0)))
+ (and (< here (point))
+ (or (not (match-beginning 0))
+ (looking-at "[ \t]*$"))))
+ ;; The comment is either one line or the next line
+ ;; contains just the comment ender. Also, if point is
+ ;; on the comment opener line and the following line is
+ ;; empty or doesn't match c-comment-prefix-regexp we
+ ;; assume that this is in fact a not yet closed one line
+ ;; comment, so we shouldn't look for the comment prefix
+ ;; on the next line. In these cases we have no
+ ;; information about a suitable comment prefix, so we
+ ;; resort to c-block-comment-prefix.
+ (setq comment-prefix (or c-block-comment-prefix "")
+ res (let ((buffer-modified (buffer-modified-p))
+ (buffer-undo-list t)
+ tmp-pre tmp-post)
+ ;; The comment doesn't give any information
+ ;; about the indentation column. We'll have to
+ ;; temporarily insert a new comment line and
+ ;; indent it to find the correct column.
+ (unwind-protect
+ (progn
+ (goto-char (car lit-limits))
+ (if (looking-at comment-start-regexp)
+ (goto-char (match-end 0))
+ (forward-char 2)
+ (skip-chars-forward " \t"))
+ (when (eq (char-syntax (char-before)) ?\ )
+ ;; If there's ws on the current
+ ;; line, we'll use it instead of
+ ;; what's ending comment-prefix.
+ (setq comment-prefix
+ (concat (substring comment-prefix
+ 0 (string-match
+ "\\s *\\'"
+ comment-prefix))
+ (buffer-substring-no-properties
+ (save-excursion
+ (skip-chars-backward " \t")
+ (point))
+ (point)))))
+ (setq tmp-pre (point-marker))
+ ;; We insert an extra non-whitespace
+ ;; character before the line break and
+ ;; after comment-prefix in case it's
+ ;; "" or ends with whitespace.
+ (insert "x\n" comment-prefix ?x)
+ (setq tmp-post (point-marker))
+ (c-indent-line)
+ (goto-char (1- tmp-post))
+ (cons (buffer-substring-no-properties
+ (c-point 'bol) (point))
+ (current-column)))
+ (when tmp-post
+ (delete-region tmp-pre tmp-post)
+ (set-marker tmp-pre nil)
+ (set-marker tmp-post nil))
+ (set-buffer-modified-p buffer-modified))))
+ ;; Otherwise the line after the comment starter is good
+ ;; enough to find the prefix in.
+ (setq prefix-line (point)))))))
+ (or res
+ (save-excursion
+ ;; prefix-line is the bol of a line on which we should try
+ ;; to find the prefix.
+ (let* (fb-string fb-endpos ; Contains any fallback prefix found.
+ (test-line
+ (lambda ()
+ (when (and (looking-at prefix-regexp)
+ (< (match-end 0) (1- (cdr lit-limits))))
+ (unless fb-string
+ (setq fb-string (buffer-substring-no-properties
+ (match-beginning 0) (match-end 0))
+ fb-endpos (match-end 0)))
+ (unless (eq (match-end 0) (c-point 'eol))
+ (throw 'found t))
+ t))))
+ (if (catch 'found
+ ;; Search for a line which has text after the prefix
+ ;; so that we get the proper amount of whitespace
+ ;; after it. We start with the current line, then
+ ;; search backwards, then forwards.
+ (goto-char prefix-line)
+ (when (and (funcall test-line)
+ (/= (match-end 1) (match-end 0)))
+ ;; If the current line doesn't have text but do
+ ;; have whitespace after the prefix, we'll use it.
+ (throw 'found t))
+ (while (and (zerop (forward-line -1))
+ (> (point) (car lit-limits)))
+ (funcall test-line))
+ (goto-char prefix-line)
+ (while (and (zerop (forward-line 1))
+ (< (point) (cdr lit-limits)))
+ (funcall test-line))
+ nil)
+ ;; A good line with text after the prefix was found.
+ (cons (buffer-substring-no-properties (point) (match-end 0))
+ (progn (goto-char (match-end 0)) (current-column)))
+ (if fb-string
+ ;; A good line wasn't found, but at least we have a
+ ;; fallback that matches the comment prefix regexp.
+ (cond ((string-match "\\s \\'" fb-string)
+ ;; There are ws after the prefix, so let's use it.
+ (cons fb-string
+ (progn (goto-char fb-endpos) (current-column))))
+ ((progn
+ ;; Check if there's any whitespace padding
+ ;; on the comment start line that we can
+ ;; use after the prefix.
+ (goto-char (car lit-limits))
+ (if (looking-at comment-start-regexp)
+ (goto-char (match-end 0))
+ (forward-char 2)
+ (skip-chars-forward " \t"))
+ (eq (char-syntax (char-before)) ?\ ))
+ (setq fb-string (buffer-substring-no-properties
+ (save-excursion
+ (skip-chars-backward " \t")
+ (point))
+ (point)))
+ (goto-char fb-endpos)
+ (skip-chars-backward " \t")
+ (let ((buffer-modified (buffer-modified-p))
+ (buffer-undo-list t)
+ (tmp (point)))
+ ;; Got to mess in the buffer once again to
+ ;; ensure the column gets correct. :P
+ (unwind-protect
+ (progn
+ (insert fb-string)
+ (cons (buffer-substring-no-properties
+ (c-point 'bol)
+ (point))
+ (current-column)))
+ (delete-region tmp (point)))))
+ (t
+ ;; Last resort: Just add a single space after
+ ;; the prefix.
+ (cons (concat fb-string " ")
+ (progn (goto-char fb-endpos)
+ (1+ (current-column))))))
+ ;; The line doesn't match the comment prefix regexp.
+ (if comment-prefix
+ ;; We have a fallback for line comments that we must use.
+ (cons (concat (buffer-substring-no-properties
+ prefix-line (c-point 'boi))
+ comment-prefix)
+ (progn (back-to-indentation)
+ (+ (current-column) (length comment-prefix))))
+ ;; Assume we are dealing with a "free text" block
+ ;; comment where the lines doesn't have any comment
+ ;; prefix at all and we should just fill it as
+ ;; normal text.
+ '("" . 0)))))))
+ ))
+
(defun c-fill-paragraph (&optional arg)
"Like \\[fill-paragraph] but handles C and C++ style comments.
-If any of the current line is a comment or within a comment,
-fill the comment or the paragraph of it that point is in,
-preserving the comment indentation or line-starting decorations.
+If any of the current line is a comment or within a comment, fill the
+comment or the paragraph of it that point is in, preserving the
+comment indentation or line-starting decorations (see the
+`c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
+details).
If point is inside multiline string literal, fill it. This currently
does not respect escaped newlines, except for the special case when it
Optional prefix ARG means justify paragraph as well."
(interactive "*P")
- (let* ((point-save (point-marker))
- limits
- comment-start-place
- (first-line
- ;; Check for obvious entry to comment.
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (and (looking-at comment-start-skip)
- (setq comment-start-place (point)))))
- (re1 "\\|\\([ \t]*/\\*[ \t]*\\|[ \t]*\\*/[ \t]*\\|[ \t/*]*\\)"))
- (if (save-excursion
- (beginning-of-line)
- (looking-at ".*//"))
- (let ((fill-prefix fill-prefix)
- ;; Lines containing just a comment start or just an end
- ;; should not be filled into paragraphs they are next
- ;; to.
- (paragraph-start (concat paragraph-start re1 "$"))
- (paragraph-separate (concat paragraph-separate re1 "$")))
- (save-excursion
- (beginning-of-line)
- ;; Move up to first line of this comment.
- (while (and (not (bobp))
- (looking-at "[ \t]*//[ \t]*[^ \t\n]"))
- (forward-line -1))
- (if (not (looking-at ".*//[ \t]*[^ \t\n]"))
- (forward-line 1))
- ;; Find the comment start in this line.
- (re-search-forward "[ \t]*//[ \t]*")
- ;; Set the fill-prefix to be what all lines except the first
- ;; should start with. But do not alter a user set fill-prefix.
- (if (null fill-prefix)
- (setq fill-prefix (buffer-substring (match-beginning 0)
- (match-end 0))))
- (save-restriction
- ;; Narrow down to just the lines of this comment.
- (narrow-to-region (c-point 'bol)
- (save-excursion
- (forward-line 1)
- (while
- (looking-at (regexp-quote fill-prefix))
- (forward-line 1))
- (point)))
- (or (c-safe
- ;; fill-paragraph sometimes fails to detect when we
- ;; are between paragraphs.
- (beginning-of-line)
- (search-forward fill-prefix (c-point 'eol))
- (looking-at paragraph-separate))
- ;; Avoids recursion
- (let (fill-paragraph-function)
- (fill-paragraph arg))))))
- ;; else C style comments
- (if (or first-line
- ;; t if we enter a comment between start of function and
- ;; this line.
+ (let (lit-limits lit-type fill
+ ;; beg and end limits the region to be filled. end is a marker.
+ beg end
+ ;; tmp-pre and tmp-post marks strings that are temporarily
+ ;; inserted at the start and end of the region. tmp-pre is a
+ ;; cons of the positions of the prepended string. tmp-post is
+ ;; a marker pointing to the single character of the appended
+ ;; string.
+ tmp-pre tmp-post
+ hang-ender-stuck)
+ ;; Restore point on undo. It's necessary since we do a lot of
+ ;; hidden inserts and deletes below that should be as transparent
+ ;; as possible.
+ (if (and buffer-undo-list (not (eq buffer-undo-list t)))
+ (setq buffer-undo-list (cons (point) buffer-undo-list)))
+ (save-excursion
+ (save-restriction
+ ;; Widen to catch comment limits correctly.
+ (widen)
+ (setq lit-limits (c-collect-line-comments (c-literal-limits nil t))
+ lit-type (c-literal-type lit-limits)))
+ (forward-paragraph)
+ (setq end (point-marker))
+ (backward-paragraph)
+ (setq beg (point)))
+ (when (and (>= (point) beg) (<= (point) end))
+ (unwind-protect
+ (progn
+ (cond
+ ((eq lit-type 'c++) ; Line comment.
(save-excursion
- (setq limits (c-literal-limits))
- (and (consp limits)
- (save-excursion
- (goto-char (car limits))
- (looking-at c-comment-start-regexp))))
- ;; t if this line contains a comment starter.
- (setq first-line
- (save-excursion
- (beginning-of-line)
- (prog1
- (re-search-forward comment-start-skip
- (save-excursion (end-of-line)
- (point))
- t)
- (setq comment-start-place (point)))))
- ;; t if we're in the whitespace after a comment ender
- ;; which ends its line.
- (and (not limits)
- (when (and (looking-at "[ \t]*$")
- (save-excursion
- (beginning-of-line)
- (looking-at ".*\\*/[ \t]*$")))
- (save-excursion
- (forward-comment -1)
- (setq comment-start-place (point)))
- t)))
- ;; Inside a comment: fill one comment paragraph.
- (let ((fill-prefix
- (or
- ;; Keep user set fill prefix if any.
- fill-prefix
- ;; The prefix for each line of this paragraph
- ;; is the appropriate part of the start of this line,
- ;; up to the column at which text should be indented.
- (save-excursion
- (beginning-of-line)
- (if (looking-at ".*/\\*.*\\*/")
- (progn (re-search-forward comment-start-skip)
- (make-string (current-column) ?\ ))
- (if first-line
- (forward-line 1)
- (if (and (looking-at "[ \t]*\\*/")
- (not (save-excursion
- (forward-line -1)
- (looking-at ".*/\\*"))))
- (forward-line -1)))
-
- (let ((line-width (progn (end-of-line)
- (current-column))))
- (beginning-of-line)
- (prog1
- (buffer-substring
- (point)
-
- ;; How shall we decide where the end of the
- ;; fill-prefix is?
- (progn
- (skip-chars-forward " \t*" (c-point 'eol))
- ;; kludge alert, watch out for */, in
- ;; which case fill-prefix should *not*
- ;; be "*"!
- (if (and (eq (char-after) ?/)
- (eq (char-before) ?*))
- (forward-char -1))
- (point)))
-
- ;; If the comment is only one line followed
- ;; by a blank line, calling move-to-column
- ;; above may have added some spaces and tabs
- ;; to the end of the line; the fill-paragraph
- ;; function will then delete it and the
- ;; newline following it, so we'll lose a
- ;; blank line when we shouldn't. So delete
- ;; anything move-to-column added to the end
- ;; of the line. We record the line width
- ;; instead of the position of the old line
- ;; end because move-to-column might break a
- ;; tab into spaces, and the new characters
- ;; introduced there shouldn't be deleted.
-
- ;; If you can see a better way to do this,
- ;; please make the change. This seems very
- ;; messy to me.
- (delete-region (progn (move-to-column line-width)
- (point))
- (progn (end-of-line) (point)))))))))
-
- ;; Lines containing just a comment start or just an end
- ;; should not be filled into paragraphs they are next
- ;; to.
- (paragraph-start (if (c-major-mode-is 'java-mode)
- (concat paragraph-start
- re1 "\\("
- c-Java-javadoc-paragraph-start
- "\\|$\\)")
- (concat paragraph-start re1 "$")))
- (paragraph-separate (concat paragraph-separate re1 "$"))
- (chars-to-delete 0)
- )
- (save-restriction
- ;; Don't fill the comment together with the code
- ;; following it. So temporarily exclude everything
- ;; before the comment start, and everything after the
- ;; line where the comment ends. If comment-start-place
- ;; is non-nil, the comment starter is there. Otherwise,
- ;; point is inside the comment.
- (narrow-to-region (save-excursion
- (if comment-start-place
- (goto-char comment-start-place)
- (search-backward "/*"))
- (if (and (not c-hanging-comment-starter-p)
- (looking-at
- (concat c-comment-start-regexp
- "[ \t]*$")))
- (forward-line 1))
- ;; Protect text before the comment
- ;; start by excluding it. Add
- ;; spaces to bring back proper
- ;; indentation of that point.
- (let ((column (current-column)))
- (prog1 (point)
- (setq chars-to-delete column)
- (insert-char ?\ column))))
- (save-excursion
- (if comment-start-place
- (goto-char (+ comment-start-place 2)))
- (search-forward "*/" nil 'move)
- (if (and (not c-hanging-comment-ender-p)
- (save-excursion
- (beginning-of-line)
- (looking-at "[ \t]*\\*/")))
- (beginning-of-line)
- (forward-line 1))
- (point)))
- (or (c-safe
- ;; fill-paragraph sometimes fails to detect when we
- ;; are between paragraphs.
- (beginning-of-line)
- (search-forward fill-prefix (c-point 'eol))
- (looking-at paragraph-separate))
- ;; Avoids recursion
- (let (fill-paragraph-function)
- (fill-paragraph arg)))
+ ;; Fill to the comment or paragraph end, whichever
+ ;; comes first.
+ (set-marker end (min end (cdr lit-limits)))
+ (when (<= beg (car lit-limits))
+ ;; The region to be filled includes the comment
+ ;; starter, so we must check it.
+ (goto-char (car lit-limits))
+ (back-to-indentation)
+ (if (eq (point) (car lit-limits))
+ ;; Include the first line in the fill.
+ (setq beg (c-point 'bol))
+ ;; The first line contains code before the
+ ;; comment. We must fake a line that doesn't.
+ (setq tmp-pre t)))
+ ))
+ ((eq lit-type 'c) ; Block comment.
(save-excursion
- ;; Delete the chars we inserted to avoid clobbering
- ;; the stuff before the comment start.
- (goto-char (point-min))
- (if (> chars-to-delete 0)
- (delete-region (point) (+ (point) chars-to-delete)))
- ;; Find the comment ender (should be on last line of
- ;; buffer, given the narrowing) and don't leave it on
- ;; its own line, unless that's the style that's desired.
- (goto-char (point-max))
- (forward-line -1)
- (search-forward "*/" nil 'move)
- (beginning-of-line)
- (if (and c-hanging-comment-ender-p
- (looking-at "[ \t]*\\*/"))
- ;(delete-indentation)))))
- (let ((fill-column (+ fill-column 9999)))
+ (when (>= end (cdr lit-limits))
+ ;; The region to be filled includes the comment ender.
+ (goto-char (cdr lit-limits))
+ (beginning-of-line)
+ (if (and (looking-at (concat "[ \t]*\\("
+ c-comment-prefix-regexp
+ "\\)\\*/"))
+ (eq (cdr lit-limits) (match-end 0)))
+ ;; Leave the comment ender on its own line.
+ (set-marker end (point))
+ ;; The comment ender should hang. Replace all
+ ;; cruft between it and the last word with a 'x'
+ ;; and include it in the fill. We'll change it
+ ;; back to a space afterwards.
+ (let ((ender-start (progn
+ (goto-char (cdr lit-limits))
+ (skip-syntax-backward "^w ")
+ (point))))
+ (goto-char (cdr lit-limits))
+ (setq tmp-post (point-marker))
+ (insert ?\n)
+ (set-marker end (point))
(forward-line -1)
- (fill-region-as-paragraph (point) (point-max))
- ;; If fill-prefix ended with a `*', it may be
- ;; taken away from the comment ender. We got to
- ;; check this and put it back if that is the
- ;; case.
- (goto-char (- (point-max) 2))
- (if (not (= (char-before) ?*))
- (insert ?*))
- )))))
- ;; Else maybe a string. Fill it if it's a multiline string.
- ;; FIXME: This currently doesn't handle escaped newlines.
- ;; Doing that correctly is a bit tricky.
- (if (and limits
- (eq (char-syntax (char-after (car limits))) ?\")
- (save-excursion
- (goto-char (car limits))
- (end-of-line)
- (< (point) (cdr limits))))
- (let (fill-paragraph-function)
- (save-restriction
- (narrow-to-region (save-excursion
- (goto-char (1+ (car limits)))
- (if (looking-at "\\\\$")
- ;; Some DWIM: Leave the start
- ;; line if it's nothing but an
- ;; escaped newline.
- (1+ (match-end 0))
- (point)))
- (save-excursion
- (goto-char (1- (cdr limits)))
- ;; Inserting a newline and
- ;; removing it again after
- ;; fill-paragraph makes it more
- ;; predictable.
- (insert ?\n)
- (point)))
- ;; Do not compensate for the narrowed column. This
- ;; way the literal will always be filled at the same
- ;; column internally.
- (fill-paragraph arg)
- (goto-char (1- (point-max)))
- (delete-char 1)))
- )))
- (goto-char (marker-position point-save))
- (set-marker point-save nil)
- ;; Always return t. This has the effect that if filling isn't
- ;; done above, it isn't done at all, and it's therefore
- ;; effectively disabled in normal code.
- t))
+ (if (and (looking-at (concat "[ \t]*\\("
+ c-comment-prefix-regexp
+ "\\)[ \t]*"))
+ (eq ender-start (match-end 0)))
+ ;; The comment ender is prefixed by nothing
+ ;; but a comment line prefix. Remove it
+ ;; along with surrounding ws.
+ nil
+ (goto-char ender-start))
+ (skip-chars-backward " \t\r\n")
+ (when (/= (point) ender-start)
+ (insert ?x) ; Insert first to keep marks right.
+ (delete-region (point) (1+ ender-start))
+ (setq hang-ender-stuck t)))))
+ (when (<= beg (car lit-limits))
+ ;; The region to be filled includes the comment starter.
+ (goto-char (car lit-limits))
+ (if (looking-at (concat "\\(" comment-start-skip "\\)$"))
+ ;; Begin filling with the next line.
+ (setq beg (c-point 'bonl))
+ ;; Fake the fill prefix in the first line.
+ (setq tmp-pre t)))
+ ))
+ ((eq lit-type 'string) ; String.
+ (save-excursion
+ (when (>= end (cdr lit-limits))
+ (goto-char (1- (cdr lit-limits)))
+ (setq tmp-post (point-marker))
+ (insert ?\n)
+ (set-marker end (point)))
+ (when (<= beg (car lit-limits))
+ (goto-char (1+ (car lit-limits)))
+ (setq beg (if (looking-at "\\\\$")
+ ;; Leave the start line if it's
+ ;; nothing but an escaped newline.
+ (1+ (match-end 0))
+ (point))))))
+ (t (setq beg nil)))
+ (when tmp-pre
+ ;; Temporarily insert the fill prefix after the comment
+ ;; starter so that the first line looks like any other
+ ;; comment line in the narrowed region.
+ (setq fill (c-guess-fill-prefix lit-limits lit-type))
+ (unless (string-match (concat "\\`[ \t]*\\("
+ c-comment-prefix-regexp
+ "\\)[ \t]*\\'")
+ (car fill))
+ ;; Oops, the prefix doesn't match the comment prefix
+ ;; regexp. This could produce very confusing
+ ;; results with adaptive fill packages together with
+ ;; the insert prefix magic below, since the prefix
+ ;; often doesn't appear at all. So let's warn about
+ ;; it.
+ (message "\
+Warning: `c-comment-prefix-regexp' doesn't match the comment prefix %S"
+ (car fill)))
+ ;; Find the right spot on the line, break it, insert
+ ;; the fill prefix and make sure we're back in the
+ ;; same column by temporarily prefixing the first word
+ ;; with a number of 'x'.
+ (save-excursion
+ (goto-char (car lit-limits))
+ (if (looking-at (if (eq lit-type 'c++)
+ c-comment-prefix-regexp
+ comment-start-skip))
+ (goto-char (match-end 0))
+ (forward-char 2)
+ (skip-chars-forward " \t"))
+ (while (< (current-column) (cdr fill)) (forward-char 1))
+ (let ((col (current-column)))
+ (setq beg (1+ (point))
+ tmp-pre (list (point)))
+ (unwind-protect
+ (progn
+ (insert ?\n (car fill))
+ (insert (make-string (- col (current-column)) ?x)))
+ (setcdr tmp-pre (point))))))
+ (when beg
+ (let ((fill-paragraph-function
+ ;; Avoid infinite recursion.
+ (if (not (eq fill-paragraph-function 'c-fill-paragraph))
+ fill-paragraph-function))
+ (fill-prefix
+ (or fill-prefix
+ (when (and (eq lit-type 'c++)
+ (not (string-match
+ "\\`[ \t]*//"
+ (or (fill-context-prefix beg end)
+ ""))))
+ ;; Kludge: If the function that adapts the
+ ;; fill prefix doesn't produce the required
+ ;; comment starter for line comments, then
+ ;; force it by setting fill-prefix.
+ (car (or fill (c-guess-fill-prefix
+ lit-limits lit-type)))))))
+ ;; Preparations finally done! Now we can call the
+ ;; real fill function.
+ (save-restriction
+ (narrow-to-region beg end)
+ (fill-paragraph arg)))))
+ (when (consp tmp-pre)
+ (delete-region (car tmp-pre) (cdr tmp-pre)))
+ (when tmp-post
+ (save-excursion
+ (goto-char tmp-post)
+ (delete-char 1)
+ (when hang-ender-stuck
+ (skip-syntax-backward "^w ")
+ (forward-char -1)
+ (insert ?\ )
+ (delete-char 1))
+ (set-marker tmp-post nil)))))
+ (set-marker end nil))
+ ;; Always return t. This has the effect that if filling isn't done
+ ;; above, it isn't done at all, and it's therefore effectively
+ ;; disabled in normal code.
+ t)
+
+(defun c-do-auto-fill ()
+ ;; Do automatic filling if not inside a context where it should be
+ ;; ignored.
+ (let ((c-auto-fill-prefix
+ ;; The decision whether the line should be broken is actually
+ ;; done in c-indent-new-comment-line, which do-auto-fill
+ ;; calls to break lines. We just set this special variable
+ ;; so that we'll know when we're called from there. It's
+ ;; also used to detect whether fill-prefix is user set or
+ ;; generated automatically by do-auto-fill.
+ fill-prefix))
+ (do-auto-fill)))
+
+(defun c-indent-new-comment-line (&optional soft)
+ "Break line at point and indent, continuing comment if within one.
+If inside a comment and `comment-multi-line' is non-nil, the
+indentation and line prefix are preserved (see the
+`c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
+details). If inside a comment and `comment-multi-line' is nil, a new
+comment of the same type is started on the next line and indented as
+appropriate for comments.
+
+If a fill prefix is specified, it overrides all the above."
+ (interactive)
+ (let ((fill-prefix fill-prefix)
+ (do-line-break
+ (lambda ()
+ (delete-region (progn (skip-chars-backward " \t") (point))
+ (progn (skip-chars-forward " \t") (point)))
+ (if soft (insert-and-inherit ?\n) (newline 1))))
+ ;; Already know the literal type and limits when called from
+ ;; c-context-line-break.
+ (c-lit-limits (if (boundp 'c-lit-limits) c-lit-limits))
+ (c-lit-type (if (boundp 'c-lit-type) c-lit-type)))
+ (when (boundp 'c-auto-fill-prefix)
+ ;; Called from do-auto-fill.
+ (unless c-lit-limits
+ (setq c-lit-limits (c-literal-limits nil nil t)))
+ (unless c-lit-type
+ (setq c-lit-type (c-literal-type c-lit-limits)))
+ (if (memq (cond ((eq c-lit-type 'pound)
+ ;; Come to think about it, "pound" is a bit
+ ;; of a misnomer, so call it "cpp" instead
+ ;; in user interaction.
+ 'cpp)
+ ((null c-lit-type) 'code)
+ (t c-lit-type))
+ c-ignore-auto-fill)
+ (setq fill-prefix t) ; Used as flag in the cond.
+ (if (null c-auto-fill-prefix)
+ (setq fill-prefix nil))))
+ (cond ((eq fill-prefix t)
+ ;; A call from do-auto-fill which should be ignored.
+ )
+ (fill-prefix
+ ;; A fill-prefix overrides anything.
+ (funcall do-line-break)
+ (insert-and-inherit fill-prefix))
+ ((progn
+ (unless c-lit-limits
+ (setq c-lit-limits (c-literal-limits nil nil t)))
+ (unless c-lit-type
+ (setq c-lit-type (c-literal-type c-lit-limits)))
+ (memq c-lit-type '(c c++)))
+ (if comment-multi-line
+ ;; Inside a comment that should be continued.
+ (let ((fill (c-guess-fill-prefix
+ (setq c-lit-limits
+ (c-collect-line-comments c-lit-limits))
+ c-lit-type))
+ (pos (point)))
+ (if (save-excursion
+ (back-to-indentation)
+ (> (point) (car c-lit-limits))
+ (looking-at c-comment-prefix-regexp))
+ (progn
+ ;; Skip forward past the fill prefix in case
+ ;; we're standing in it.
+ (while (and (< (current-column) (cdr fill))
+ (not (eolp)))
+ (forward-char 1))
+ (if (> (point) (if (and (eq c-lit-type 'c)
+ (save-excursion
+ (forward-char -2)
+ (looking-at "\\*/")))
+ (- (cdr c-lit-limits) 2)
+ (cdr c-lit-limits)))
+ (progn
+ ;; The skip takes us out of the comment;
+ ;; insert the fill prefix at bol instead
+ ;; and keep the position.
+ (setq pos (copy-marker pos t))
+ (beginning-of-line)
+ (insert-and-inherit (car fill))
+ (if soft (insert-and-inherit ?\n) (newline 1))
+ (goto-char pos)
+ (set-marker pos nil))
+ (funcall do-line-break)
+ (insert-and-inherit (car fill))))
+ (funcall do-line-break)
+ (insert-and-inherit (car fill))))
+ ;; Inside a comment that should be broken.
+ (let ((comment-start comment-start)
+ (comment-end comment-end)
+ col)
+ (if (eq c-lit-type 'c)
+ (unless (string-match "[ \t]*/\\*" comment-start)
+ (setq comment-start "/* " comment-end " */"))
+ (unless (string-match "[ \t]*//" comment-start)
+ (setq comment-start "// " comment-end "")))
+ (setq col (save-excursion
+ (back-to-indentation)
+ (current-column)))
+ (funcall do-line-break)
+ (when (and comment-end (not (equal comment-end "")))
+ (forward-char -1)
+ (insert-and-inherit comment-end)
+ (forward-char 1))
+ ;; c-comment-indent may look at the current
+ ;; indentation, so let's start out with the same
+ ;; indentation as the previous one.
+ (indent-to col)
+ (insert-and-inherit comment-start)
+ (indent-for-comment))))
+ (t
+ ;; Somewhere else in the code.
+ (let ((col (save-excursion
+ (while (progn (back-to-indentation)
+ (and (looking-at "^\\s *$")
+ (= (forward-line -1) 0))))
+ (current-column))))
+ (funcall do-line-break)
+ (indent-to col))))))
+
+(defalias 'c-comment-line-break-function 'c-indent-new-comment-line)
+(make-obsolete 'c-comment-line-break-function 'c-indent-new-comment-line)
+
+;; advice for indent-new-comment-line for older Emacsen
+(unless (boundp 'comment-line-break-function)
+ (defadvice indent-new-comment-line (around c-line-break-advice
+ activate preactivate)
+ "Call `c-indent-new-comment-line' if in CC Mode."
+ (if (or (boundp 'c-inside-line-break-advice)
+ (not c-buffer-is-cc-mode))
+ ad-do-it
+ (let (c-inside-line-break-advice)
+ (c-indent-new-comment-line (ad-get-arg 0))))))
+
+(defun c-context-line-break ()
+ "Do a line break suitable to the context.
+
+When point is outside a comment, insert a newline and indent according
+to the syntactic context.
+
+When point is inside a comment, continue it with the appropriate
+comment prefix (see the `c-comment-prefix-regexp' and
+`c-block-comment-prefix' variables for details). The end of a
+C++-style line comment doesn't count as inside the comment, though."
+ (interactive "*")
+ (let* ((c-lit-limits (c-literal-limits nil nil t))
+ (c-lit-type (c-literal-type c-lit-limits)))
+ (if (or (eq c-lit-type 'c)
+ (and (eq c-lit-type 'c++)
+ (< (point)
+ (1- (cdr (setq c-lit-limits
+ (c-collect-line-comments c-lit-limits)))))))
+ (let ((comment-multi-line t)
+ (fill-prefix nil))
+ (c-indent-new-comment-line))
+ (delete-region (point) (progn (skip-chars-backward " \t") (point)))
+ (newline)
+ ;; c-indent-line may look at the current indentation, so let's
+ ;; start out with the same indentation as the previous line.
+ (let ((col (save-excursion
+ (forward-line -1)
+ (while (progn (back-to-indentation)
+ (and (looking-at "^\\s *$")
+ (= (forward-line -1) 0))))
+ (current-column))))
+ (indent-to col))
+ (c-indent-line))))
\f
(provide 'cc-cmds)
;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
;; Author: 1994-1997 Barry A. Warsaw
-;; Maintainer: bug-cc-mode@gnu.org
+;; Maintainer: Unmaintained
;; Created: August 1994, split from cc-mode.el
;; Version: See cc-mode.el
;; Keywords: c languages oop
;;; Code:
(eval-when-compile
- (require 'cc-defs)
- (require 'cc-styles)
- (require 'cc-engine))
+ (let ((load-path
+ (if (and (boundp 'byte-compile-current-file)
+ (stringp byte-compile-current-file))
+ (cons (file-name-directory byte-compile-current-file)
+ load-path)
+ load-path)))
+ (load "cc-defs" nil t)))
+(require 'cc-styles)
+(require 'cc-engine)
\f
;; In case c-mode.el isn't loaded
;;; cc-defs.el --- compile time definitions for CC Mode
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
-;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-\f
;; Get all the necessary compile time definitions.
(require 'custom)
-(require 'cc-menus)
(require 'derived) ;only necessary in Emacs 20
;; cc-mode-19.el contains compatibility macros that should be compiled
(require 'cc-mode-19))
\f
-(defsubst c-point (position)
+(defmacro c-point (position)
;; Returns the value of point at certain commonly referenced POSITIONs.
;; POSITION can be one of the following symbols:
;;
;; bopl -- beginning of previous line
;;
;; This function does not modify point or mark.
- (let ((here (point)))
- (cond
- ((eq position 'bol) (beginning-of-line))
- ((eq position 'eol) (end-of-line))
- ((eq position 'boi) (back-to-indentation))
- ((eq position 'bonl) (forward-line 1))
- ((eq position 'bopl) (forward-line -1))
- ((eq position 'iopl)
- (forward-line -1)
- (back-to-indentation))
- ((eq position 'ionl)
- (forward-line 1)
- (back-to-indentation))
- ((eq position 'eod) (c-end-of-defun))
- ((eq position 'bod)
- (if (and (fboundp 'buffer-syntactic-context-depth)
- c-enable-xemacs-performance-kludge-p)
- ;; XEmacs only. This can improve the performance of
- ;; c-parse-state to between 3 and 60 times faster when
- ;; braces are hung. It can also degrade performance by
- ;; about as much when braces are not hung.
- (let (pos)
- (while (not pos)
- (save-restriction
- (widen)
- (setq pos (scan-lists (point) -1
- (buffer-syntactic-context-depth)
- nil t)))
- (cond
- ((bobp) (setq pos (point-min)))
- ((not pos)
- (let ((distance (skip-chars-backward "^{")))
- ;; unbalanced parenthesis, while illegal C code,
- ;; shouldn't cause an infloop! See unbal.c
- (when (zerop distance)
- ;; Punt!
- (beginning-of-defun)
- (setq pos (point)))))
- ((= pos 0))
- ((not (eq (char-after pos) ?{))
- (goto-char pos)
- (setq pos nil))
- ))
- (goto-char pos))
- ;; Emacs, which doesn't have buffer-syntactic-context-depth
- ;;
- ;; NOTE: This should be the only explicit use of
- ;; beginning-of-defun in CC Mode. Eventually something better
- ;; than b-o-d will be available and this should be the only
- ;; place the code needs to change. Everything else should use
- ;; (goto-char (c-point 'bod))
- (beginning-of-defun)
- ;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at
- ;; the open brace.
- (and defun-prompt-regexp
- (looking-at defun-prompt-regexp)
- (goto-char (match-end 0)))
- ))
- (t (error "unknown buffer position requested: %s" position))
- )
- (prog1
- (point)
- (goto-char here))))
+ `(save-excursion
+ ,(if (and (eq (car-safe position) 'quote)
+ (symbolp (eval position)))
+ (let ((position (eval position)))
+ (cond
+ ((eq position 'bol) `(beginning-of-line))
+ ((eq position 'eol) `(end-of-line))
+ ((eq position 'boi) `(back-to-indentation))
+ ((eq position 'bonl) `(forward-line 1))
+ ((eq position 'bopl) `(forward-line -1))
+ ((eq position 'bod) `(c-beginning-of-defun-1))
+ ((eq position 'eod) `(c-end-of-defun-1))
+ ((eq position 'iopl) `(progn
+ (forward-line -1)
+ (back-to-indentation)))
+ ((eq position 'ionl) `(progn
+ (forward-line 1)
+ (back-to-indentation)))
+ (t (error "unknown buffer position requested: %s" position))))
+ ;;(message "c-point long expansion")
+ `(let ((position ,position))
+ (cond
+ ((eq position 'bol) (beginning-of-line))
+ ((eq position 'eol) (end-of-line))
+ ((eq position 'boi) (back-to-indentation))
+ ((eq position 'bonl) (forward-line 1))
+ ((eq position 'bopl) (forward-line -1))
+ ((eq position 'bod) (c-beginning-of-defun-1))
+ ((eq position 'eod) (c-end-of-defun-1))
+ ((eq position 'iopl) (progn
+ (forward-line -1)
+ (back-to-indentation)))
+ ((eq position 'ionl) (progn
+ (forward-line 1)
+ (back-to-indentation)))
+ (t (error "unknown buffer position requested: %s" position)))))
+ (point)))
\f
(defmacro c-safe (&rest body)
;; safely execute BODY, return nil if an error occurred
- (` (condition-case nil
- (progn (,@ body))
- (error nil))))
+ `(condition-case nil
+ (progn ,@body)
+ (error nil)))
+
+(defsubst c-beginning-of-defun-1 ()
+ ;; Wrapper around beginning-of-defun.
+ ;;
+ ;; NOTE: This function should contain the only explicit use of
+ ;; beginning-of-defun in CC Mode. Eventually something better than
+ ;; b-o-d will be available and this should be the only place the
+ ;; code needs to change. Everything else should use
+ ;; (c-beginning-of-defun-1)
+ (if (and (fboundp 'buffer-syntactic-context-depth)
+ c-enable-xemacs-performance-kludge-p)
+ ;; XEmacs only. This can improve the performance of
+ ;; c-parse-state to between 3 and 60 times faster when
+ ;; braces are hung. It can also degrade performance by
+ ;; about as much when braces are not hung.
+ (let (pos)
+ (while (not pos)
+ (save-restriction
+ (widen)
+ (setq pos (scan-lists (point) -1
+ (buffer-syntactic-context-depth)
+ nil t)))
+ (cond
+ ((bobp) (setq pos (point-min)))
+ ((not pos)
+ (let ((distance (skip-chars-backward "^{")))
+ ;; unbalanced parenthesis, while illegal C code,
+ ;; shouldn't cause an infloop! See unbal.c
+ (when (zerop distance)
+ ;; Punt!
+ (beginning-of-defun)
+ (setq pos (point)))))
+ ((= pos 0))
+ ((not (eq (char-after pos) ?{))
+ (goto-char pos)
+ (setq pos nil))
+ ))
+ (goto-char pos))
+ ;; Emacs, which doesn't have buffer-syntactic-context-depth
+ (beginning-of-defun))
+ ;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at the
+ ;; open brace.
+ (and defun-prompt-regexp
+ (looking-at defun-prompt-regexp)
+ (goto-char (match-end 0))))
+
+(defsubst c-end-of-defun-1 ()
+ ;; Replacement for end-of-defun that use c-beginning-of-defun-1.
+ (while (and (c-safe (down-list 1) t)
+ (not (eq (char-before) ?{)))
+ ;; skip down into the next defun-block
+ (forward-char -1)
+ (c-forward-sexp))
+ (c-beginning-of-defun-1)
+ (c-forward-sexp))
(defmacro c-forward-sexp (&optional arg)
;; like forward-sexp except
(or arg (setq arg 1))
`(c-forward-sexp ,(if (numberp arg) (- arg) `(- ,arg))))
+(defsubst c-beginning-of-macro (&optional lim)
+ ;; Go to the beginning of a cpp macro definition. Leaves point at
+ ;; the beginning of the macro and returns t if in a cpp macro
+ ;; definition, otherwise returns nil and leaves point unchanged.
+ ;; `lim' is currently ignored, but the interface requires it.
+ (let ((here (point)))
+ (beginning-of-line)
+ (while (eq (char-before (1- (point))) ?\\)
+ (forward-line -1))
+ (back-to-indentation)
+ (if (and (<= (point) here)
+ (eq (char-after) ?#))
+ t
+ (goto-char here)
+ nil)))
+
+(defsubst c-forward-comment (count)
+ ;; Insulation from various idiosyncrasies in implementations of
+ ;; `forward-comment'. Note: Some emacsen considers incorrectly that
+ ;; any line comment ending with a backslash continues to the next
+ ;; line. I can't think of any way to work around that in a reliable
+ ;; way without changing the buffer though. Suggestions welcome. ;)
+ (let ((here (point)))
+ (if (>= count 0)
+ (when (forward-comment count)
+ ;; Emacs includes the ending newline in a b-style
+ ;; (c++) comment, but XEmacs don't. We depend on the
+ ;; Emacs behavior (which also is symmetric).
+ (if (and (eolp) (nth 7 (parse-partial-sexp here (point))))
+ (condition-case nil (forward-char 1)))
+ t)
+ ;; When we got newline terminated comments,
+ ;; forward-comment in all supported emacsen so far will
+ ;; stop at eol of each line not ending with a comment when
+ ;; moving backwards. The following corrects for it when
+ ;; count is -1. The other common case, when count is
+ ;; large and negative, works regardless. It's too much
+ ;; work to correct for the rest of the cases.
+ (skip-chars-backward " \t\n\r\f")
+ (if (bobp)
+ ;; Some emacsen return t when moving backwards at bob.
+ nil
+ (re-search-forward "[\n\r]" here t)
+ (if (forward-comment count)
+ (if (eolp) (forward-comment -1) t))))))
+
(defmacro c-add-syntax (symbol &optional relpos)
;; a simple macro to append the syntax in symbol to the syntax list.
;; try to increase performance by using this macro
- (` (setq syntax (cons (cons (, symbol) (, relpos)) syntax))))
+ `(setq syntax (cons (cons ,symbol ,relpos) syntax)))
-(defsubst c-auto-newline ()
+(defmacro c-add-class-syntax (symbol classkey)
+ ;; The inclass and class-close syntactic symbols are added in
+ ;; several places and some work is needed to fix everything.
+ ;; Therefore it's collected here.
+ `(save-restriction
+ (widen)
+ (let ((symbol ,symbol)
+ (classkey ,classkey))
+ (goto-char (aref classkey 1))
+ (if (and (eq symbol 'inclass) (= (point) (c-point 'boi)))
+ (c-add-syntax symbol (point))
+ (c-add-syntax symbol (aref classkey 0))
+ (if (and c-inexpr-class-key (c-looking-at-inexpr-block))
+ (c-add-syntax 'inexpr-class))))))
+
+(defmacro c-auto-newline ()
;; if auto-newline feature is turned on, insert a newline character
;; and return t, otherwise return nil.
- (and c-auto-newline
- (not (c-in-literal))
- (not (newline))))
+ `(and c-auto-newline
+ (not (c-in-literal))
+ (not (newline))))
(defsubst c-intersect-lists (list alist)
;; return the element of ALIST that matches the first element found
(goto-char here))
)))
-(defsubst c-update-modeline ()
+(defmacro c-update-modeline ()
;; set the c-auto-hungry-string for the correct designation on the modeline
- (setq c-auto-hungry-string
- (if c-auto-newline
- (if c-hungry-delete-key "/ah" "/a")
- (if c-hungry-delete-key "/h" nil)))
- (force-mode-line-update))
+ `(progn
+ (setq c-auto-hungry-string
+ (if c-auto-newline
+ (if c-hungry-delete-key "/ah" "/a")
+ (if c-hungry-delete-key "/h" nil)))
+ (force-mode-line-update)))
(defsubst c-keep-region-active ()
;; Do whatever is necessary to keep the region active in XEmacs.
(cond
;; XEmacs
((and (fboundp 'region-active-p)
+ (boundp 'zmacs-regions)
zmacs-regions)
(region-active-p))
;; Emacs
(defsubst c-major-mode-is (mode)
(eq (derived-mode-class major-mode) mode))
+(defmacro c-with-syntax-table (table &rest code)
+ ;; Temporarily switches to the specified syntax table in a failsafe
+ ;; way to execute code.
+ `(let ((c-with-syntax-table-orig-table (syntax-table)))
+ (unwind-protect
+ (progn
+ (set-syntax-table ,table)
+ ,@code)
+ (set-syntax-table c-with-syntax-table-orig-table))))
+(put 'c-with-syntax-table 'lisp-indent-function 1)
+
\f
(provide 'cc-defs)
;;; cc-defs.el ends here
;;; cc-engine.el --- core syntax guessing engine for CC mode
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
-;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-\f
(eval-when-compile
- (require 'cc-defs))
+ (let ((load-path
+ (if (and (boundp 'byte-compile-current-file)
+ (stringp byte-compile-current-file))
+ (cons (file-name-directory byte-compile-current-file)
+ load-path)
+ load-path)))
+ (load "cc-defs" nil t)))
+(require 'cc-langs)
+\f
;; KLUDGE ALERT: c-maybe-labelp is used to pass information between
;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A
;; better way should be implemented, but this will at least shut up
;; CASE 2: some other kind of literal?
((c-in-literal lim))
;; CASE 3: are we looking at a conditional keyword?
- ((or (looking-at c-conditional-key)
+ ((or (and c-conditional-key (looking-at c-conditional-key))
(and (eq (char-after) ?\()
(save-excursion
(c-forward-sexp 1)
(<= lim (point))
(not (c-in-literal lim))
(not (eq (char-before) ?_))
+ c-conditional-key
(looking-at c-conditional-key)
))))
;; did we find a conditional?
(setq substmt-p nil))
(setq last-begin (point)
donep substmt-p))
- ;; CASE 4: are we looking at a label?
- ((looking-at c-label-key))
+ ;; CASE 4: are we looking at a label? (But we handle
+ ;; switch labels later.)
+ ((and (looking-at c-label-key)
+ (not (looking-at "default\\>"))))
;; CASE 5: is this the first time we're checking?
(firstp (setq firstp nil
substmt-p (not (c-crosses-statement-barrier-p
;; `case' or `default' is first thing on line
(let ((here (point)))
(beginning-of-line)
- (c-forward-syntactic-ws)
+ (c-forward-syntactic-ws here)
(if (looking-at c-switch-label-key)
t
(goto-char here)
;; We always want to skip over the non-whitespace modifier
;; characters that can start a statement.
(let ((lim (point)))
- (skip-chars-backward "-+!*&~@ \t\n" (c-point 'boi))
+ (skip-chars-backward "-+!*&~@` \t\n" (c-point 'boi))
(skip-chars-forward " \t\n" lim))))
(defun c-end-of-statement-1 ()
(hugenum (point-max)))
(while (/= here (point))
(setq here (point))
- (forward-comment hugenum)
+ (c-forward-comment hugenum)
;; skip preprocessor directives
(when (and (eq (char-after) ?#)
(= (c-point 'boi) (point)))
)
(if lim (goto-char (min (point) lim)))))
-(defsubst c-beginning-of-macro (&optional lim)
- ;; Go to the beginning of a cpp macro definition. Leaves point at
- ;; the beginning of the macro and returns t if in a cpp macro
- ;; definition, otherwise returns nil and leaves point unchanged.
- ;; `lim' is currently ignored, but the interface requires it.
- (let ((here (point)))
- (beginning-of-line)
- (while (eq (char-before (1- (point))) ?\\)
- (forward-line -1))
- (back-to-indentation)
- (if (eq (char-after) ?#)
- t
- (goto-char here)
- nil)))
-
(defun c-backward-syntactic-ws (&optional lim)
;; Backward skip over syntactic whitespace for Emacs 19.
(let* ((here (point-min))
(hugenum (- (point-max))))
(while (/= here (point))
(setq here (point))
- (forward-comment hugenum)
+ (c-forward-comment hugenum)
(c-beginning-of-macro))
(if lim (goto-char (max (point) lim)))))
(if (fboundp 'buffer-syntactic-context)
(defalias 'c-in-literal 'c-fast-in-literal))
-(defun c-literal-limits (&optional lim near)
+(defun c-literal-limits (&optional lim near not-in-delimiter)
;; Returns a cons of the beginning and end positions of the comment
;; or string surrounding point (including both delimiters), or nil
;; if point isn't in one. If LIM is non-nil, it's used as the
;; "safe" position to start parsing from. If NEAR is non-nil, then
;; the limits of any literal next to point is returned. "Next to"
;; means there's only [ \t] between point and the literal. The
- ;; search for such a literal is done first in forward direction.
- ;;
- ;; This is the Emacs 19 version.
+ ;; search for such a literal is done first in forward direction. If
+ ;; NOT-IN-DELIMITER is non-nil, the case when point is inside a
+ ;; starting delimiter won't be recognized. This only has effect for
+ ;; comments, which have starting delimiters with more than one
+ ;; character.
(save-excursion
(let* ((pos (point))
(lim (or lim (c-point 'bod)))
lim (point) nil nil state)
lim (point)))
(backward-char 2)
- (cons (point) (progn (forward-comment 1) (point))))
+ (cons (point) (progn (c-forward-comment 1) (point))))
((nth 4 state)
;; Block comment. Search backward for the comment starter.
(while (nth 4 state)
(search-backward "/*") ; Should never fail.
(setq state (parse-partial-sexp lim (point))))
- (cons (point) (progn (forward-comment 1) (point))))
- ((c-safe (nth 4 (parse-partial-sexp ; Can't use prev state due
- lim (1+ (point))))) ; to bug in Emacs 19.34.
+ (cons (point) (progn (c-forward-comment 1) (point))))
+ ((and (not not-in-delimiter)
+ (not (nth 5 state))
+ (eq (char-before) ?/)
+ (looking-at "[/*]"))
;; We're standing in a comment starter.
- (backward-char 2)
- (cons (point) (progn (forward-comment 1) (point))))
+ (backward-char 1)
+ (cons (point) (progn (c-forward-comment 1) (point))))
(near
(goto-char pos)
;; Search forward for a literal.
(cons (point) (or (c-safe (c-forward-sexp 1) (point))
(point-max))))
((looking-at "/[/*]") ; Line or block comment.
- (cons (point) (progn (forward-comment 1) (point))))
+ (cons (point) (progn (c-forward-comment 1) (point))))
(t
;; Search backward.
(skip-chars-backward " \t")
;; comments, they will always be covered by the
;; normal case above.
(goto-char end)
- (forward-comment -1)
+ (c-forward-comment -1)
;; If LIM is bogus, beg will be bogus.
(setq beg (point))))
(if beg (cons beg end))))))
))))
-(defun c-literal-limits-fast (&optional lim)
+(defun c-literal-limits-fast (&optional lim near not-in-delimiter)
;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp'
- ;; returns the pos of the comment start. FIXME: Add NEAR.
+ ;; returns the pos of the comment start.
(save-excursion
- (let ((state (parse-partial-sexp lim (point))))
+ (let* ((pos (point))
+ (lim (or lim (c-point 'bod)))
+ (state (parse-partial-sexp lim (point))))
(cond ((nth 3 state) ; String.
(goto-char (nth 8 state))
(cons (point) (or (c-safe (c-forward-sexp 1) (point))
(point-max))))
((nth 4 state) ; Comment.
(goto-char (nth 8 state))
- (cons (point) (progn (forward-comment 1) (point))))
- ((c-safe
- (nth 4 (parse-partial-sexp ; Works?
- (point) (1+ (point)) nil nil state)))
- ;; We're in a comment starter.
- (backward-char 2)
- (cons (point) (progn (forward-comment 1) (point))))
+ (cons (point) (progn (c-forward-comment 1) (point))))
+ ((and (not not-in-delimiter)
+ (not (nth 5 state))
+ (eq (char-before) ?/)
+ (looking-at "[/*]"))
+ ;; We're standing in a comment starter.
+ (backward-char 1)
+ (cons (point) (progn (c-forward-comment 1) (point))))
+ (near
+ (goto-char pos)
+ ;; Search forward for a literal.
+ (skip-chars-forward " \t")
+ (cond
+ ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String.
+ (cons (point) (or (c-safe (c-forward-sexp 1) (point))
+ (point-max))))
+ ((looking-at "/[/*]") ; Line or block comment.
+ (cons (point) (progn (c-forward-comment 1) (point))))
+ (t
+ ;; Search backward.
+ (skip-chars-backward " \t")
+ (let ((end (point)) beg)
+ (cond
+ ((eq (char-syntax (or (char-before) ?\ )) ?\") ; String.
+ (setq beg (c-safe (c-backward-sexp 1) (point))))
+ ((and (c-safe (forward-char -2) t)
+ (looking-at "*/"))
+ ;; Block comment. Due to the nature of line
+ ;; comments, they will always be covered by the
+ ;; normal case above.
+ (goto-char end)
+ (c-forward-comment -1)
+ ;; If LIM is bogus, beg will be bogus.
+ (setq beg (point))))
+ (if beg (cons beg end))))))
))))
+(if (c-safe (> (length (save-excursion (parse-partial-sexp 1 1))) 8))
+ (defalias 'c-literal-limits 'c-literal-limits-fast))
+
(defun c-collect-line-comments (range)
;; If the argument is a cons of two buffer positions (such as
;; returned by c-literal-limits), and that range contains a C++
(let ((col (current-column))
(beg (point))
(end (cdr range)))
- (while (and (not (bobp))
- (forward-comment -1)
+ (while (and (c-forward-comment -1)
(looking-at "//")
(= col (current-column)))
(setq beg (point)))
(goto-char end)
- (while (progn
- (skip-chars-forward " \t")
- (and (looking-at "//")
- (= col (current-column))))
- (forward-comment 1)
- (setq end (point)))
+ (while (and (progn (skip-chars-forward " \t")
+ (looking-at "//"))
+ (= col (current-column))
+ (prog1 (zerop (forward-line 1))
+ (setq end (point)))))
(cons beg end))
range)
(error range))))
;; It's much faster than using c-in-literal and is intended to be
;; used when you need both the type of a literal and its limits.
(if (consp range)
- (save-excursion
- (goto-char (car range))
- (cond ((eq (char-syntax (or (char-after) ?\ )) ?\") 'string)
- ((looking-at "//") 'c++)
- (t 'c))) ; Assuming the range is valid.
+ (save-excursion
+ (goto-char (car range))
+ (cond ((eq (char-syntax (or (char-after) ?\ )) ?\") 'string)
+ ((looking-at "//") 'c++)
+ (t 'c))) ; Assuming the range is valid.
range))
;; backward search.
(save-excursion
(or lim (setq lim (point-min)))
- (if (and (eq (char-after) ?{)
- (progn (c-backward-syntactic-ws) (> (point) lim))
- (eq (char-before) ?\()
- (not (and c-special-brace-lists
- (c-looking-at-special-brace-list))))
- (cons 'inexpr-statement (point))
- (let (res)
- (while (and (not res)
- (= (c-backward-token-1 1 t lim) 0)
- (>= (point) lim)
- (looking-at "(\\|\\w\\|\\s_\\|\\."))
- (setq res
- (cond ((and c-inexpr-class-key
- (looking-at c-inexpr-class-key))
- (cons 'inexpr-class (point)))
- ((and c-inexpr-block-key
- (looking-at c-inexpr-block-key))
- (cons 'inexpr-statement (point)))
- ((and c-lambda-key
- (looking-at c-lambda-key))
- (cons 'inlambda (point))))))
- res))))
+ (let ((block-follows (eq (char-after) ?{)))
+ ;; Look at the character after point only as a last resort when
+ ;; we can't disambiguate.
+ (if (and block-follows
+ (progn (c-backward-syntactic-ws) (> (point) lim))
+ (eq (char-before) ?\()
+ (not (and c-special-brace-lists
+ (c-looking-at-special-brace-list))))
+ (cons 'inexpr-statement (point))
+ (let (res)
+ (while (and (not res)
+ (= (c-backward-token-1 1 t lim) 0)
+ (>= (point) lim)
+ (looking-at "(\\|\\w\\|\\s_\\|\\."))
+ (setq res
+ (cond ((and block-follows
+ c-inexpr-class-key
+ (looking-at c-inexpr-class-key))
+ (cons 'inexpr-class (point)))
+ ((and c-inexpr-block-key
+ (looking-at c-inexpr-block-key))
+ (cons 'inexpr-statement (point)))
+ ((and c-lambda-key
+ (looking-at c-lambda-key))
+ (cons 'inlambda (point))))))
+ res)))))
(defun c-looking-at-inexpr-block-backward (&optional lim)
;; Returns non-nil if we're looking at the end of an in-expression
;; return the class vector
inclass-p))
-(defsubst c-add-class-syntax (symbol classkey)
- ;; The inclass and class-close syntactic symbols are added in
- ;; several places and some work is needed to fix everything.
- ;; Therefore it's collected here.
- (save-restriction
- (widen)
- (goto-char (aref classkey 1))
- (if (and (eq symbol 'inclass) (= (point) (c-point 'boi)))
- (c-add-syntax symbol (point))
- (c-add-syntax symbol (aref classkey 0))
- (if (and c-inexpr-class-key (c-looking-at-inexpr-block))
- (c-add-syntax 'inexpr-class)))))
-
\f
;; This function implements the main decision tree for determining the
;; syntactic analysis of the current line of code. Yes, it's huge and
(c-add-syntax 'string (c-point 'bopl)))
;; CASE 2: in a C or C++ style comment.
((memq literal '(c c++))
- ;; we need to catch multi-paragraph C comments
- (while (and (zerop (forward-line -1))
- (looking-at "^[ \t]*$")))
- (c-add-syntax literal (c-point 'boi)))
+ (c-add-syntax literal (car (c-literal-limits lim))))
;; CASE 3: in a cpp preprocessor macro
((eq literal 'pound)
(let ((boi (c-point 'boi))
;; don't add inclass symbol since relative point already
;; contains any class offset
)))
- ;; CASE 5D: this could be a top-level compound statement or a
- ;; member init list continuation
- ((eq char-before-ip ?,)
+ ;; CASE 5D: this could be a top-level compound statement, a
+ ;; member init list continuation, or a template argument
+ ;; list continuation.
+ ((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
+ c++-template-syntax-table
+ (syntax-table))
+ (save-excursion
+ (while (and (= (c-backward-token-1 1 t lim) 0)
+ (not (looking-at "[;{<,]"))))
+ (eq (char-after) ?,)))
(goto-char indent-point)
(c-backward-syntactic-ws lim)
(while (and (< lim (point))
;; for bogus matches on access specifiers inside classes.
((and (save-excursion
;; There might be member inits on the first line too.
- (end-of-line)
(while (and (> (point) lim)
(eq (char-before) ?,)
(= (c-backward-token-1 2 t lim) 0)
(= (c-backward-token-1 1 t lim) 0))
(c-backward-syntactic-ws lim))
(setq placeholder (point))
- (c-backward-syntactic-ws lim)
- (eq (char-before) ?:))
+ (c-backward-token-1 1 t lim)
+ (and (eq (char-after) ?:)
+ (not (eq (char-before) ?:))))
(save-excursion
(goto-char placeholder)
(back-to-indentation)
(and
- c-access-key
- (not (looking-at c-access-key))
- (not (looking-at c-class-key)))
+ (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)
;; we can probably indent it just like an arglist-cont
(goto-char placeholder)
(c-beginning-of-statement-1 lim)
- (c-add-syntax 'template-args-cont (point)))
+ (c-add-syntax 'template-args-cont (c-point 'boi)))
;; CASE 5D.5: perhaps a top-level statement-cont
(t
(c-beginning-of-statement-1 lim)
(beginning-of-line)
(looking-at c-method-key)))
(c-add-syntax 'objc-method-args-cont (point)))
- ;; CASE 5K: we are at a topmost continuation line
+ ;; CASE 5K: 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
(t
(c-beginning-of-statement-1 lim)
(c-forward-syntactic-ws)
;; 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 (save-excursion
- (and (c-safe (c-forward-sexp -1) t)
- (looking-at c-lambda-key)))
- 'lambda-intro-cont
- 'inline-open)))
+ (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)))
(c-backward-syntactic-ws containing-sexp)
(cond
;; CASE 7A: we are looking at the arglist closing paren
- ((and (not (eq char-before-ip ?,))
+ ((and (or (c-major-mode-is 'pike-mode)
+ ;; Don't check this in Pike since it allows a
+ ;; comma after the last arg.
+ (not (eq char-before-ip ?,)))
(memq char-after-ip '(?\) ?\])))
(goto-char containing-sexp)
(c-add-syntax 'arglist-close (c-point 'boi)))
((and (consp special-brace-list)
(eq char-after-ip (car (cdr special-brace-list))))
(goto-char (car (car special-brace-list)))
- (c-beginning-of-statement-1 lim)
- (c-forward-token-1 0)
- (if (looking-at "typedef\\>") (c-forward-token-1 1))
- (c-add-syntax 'brace-list-open (c-point 'boi)))
+ (skip-chars-backward " \t")
+ (if (bolp)
+ (setq syntax (c-guess-basic-syntax))
+ (c-beginning-of-statement-1 lim)
+ (c-forward-token-1 0)
+ (if (looking-at "typedef\\>") (c-forward-token-1 1))
+ (c-add-syntax 'brace-list-open (c-point 'boi))))
;; CASE 9B: brace-list-close brace
((if (consp special-brace-list)
;; Check special brace list closer.
(let ((after-cond-placeholder
(save-excursion
(goto-char placeholder)
- (if (looking-at c-conditional-key)
+ (if (and c-conditional-key (looking-at c-conditional-key))
(progn
(c-safe (c-skip-conditional))
(c-forward-syntactic-ws)
(= (c-backward-token-1 1 t) 0)
(/= (char-after) ?=)))
(eq (char-after) ?=)))
- (c-add-syntax 'brace-list-open placeholder))
+ ;; The most semantically accurate symbol here is
+ ;; brace-list-open, but we report it simply as a
+ ;; statement-cont. The reason is that one normally
+ ;; adjusts brace-list-open for brace lists as
+ ;; top-level constructs, and brace lists inside
+ ;; statements is a completely different context.
+ (goto-char placeholder)
+ (c-add-syntax 'statement-cont (c-point 'boi)))
;; CASE 10B.3: catch-all for unknown construct.
(t
;; Can and should I add an extensibility hook here?
(setq placeholder (point))
(looking-at "do\\b[^_]"))
))
- (c-add-syntax 'do-while-closure placeholder))
+ (goto-char placeholder)
+ (c-add-syntax 'do-while-closure (c-point 'boi)))
;; CASE 13: A catch or finally clause? This case is simpler
;; than if-else and do-while, because a block is required
;; after every try, catch and finally.
))
(c-keep-region-active))
+(defun c-syntactic-information-on-region (from to)
+ "Inserts a comment with the syntactic analysis on every line in the region."
+ (interactive "*r")
+ (save-excursion
+ (save-restriction
+ (narrow-to-region from to)
+ (goto-char (point-min))
+ (while (not (eobp))
+ (c-show-syntactic-information '(0))
+ (forward-line)))))
+
\f
(provide 'cc-engine)
;;; cc-engine.el ends here
;;; cc-langs.el --- specific language support for CC Mode
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
-;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
+(eval-when-compile
+ (let ((load-path
+ (if (and (boundp 'byte-compile-current-file)
+ (stringp byte-compile-current-file))
+ (cons (file-name-directory byte-compile-current-file)
+ load-path)
+ load-path)))
+ (load "cc-defs" nil t)))
+(require 'cc-styles)
+
+;; Pull in some other packages.
+(eval-when-compile
+ (condition-case nil
+ ;; Not required and only needed during compilation to shut up
+ ;; the compiler.
+ (require 'outline)
+ (error nil)))
+;; menu support for both XEmacs and Emacs. If you don't have easymenu
+;; with your version of Emacs, you are incompatible!
+(require 'easymenu)
\f
-(eval-when-compile
- (require 'cc-defs))
+(defvar c-buffer-is-cc-mode nil
+ "Non-nil for all buffers with a `major-mode' derived from CC Mode.
+Otherwise, this variable is nil. I.e. this variable is non-nil for
+`c-mode', `c++-mode', `objc-mode', `java-mode', `idl-mode',
+`pike-mode', and any other non-CC Mode mode that calls
+`c-initialize-cc-mode' (e.g. `awk-mode').")
+(make-variable-buffer-local 'c-buffer-is-cc-mode)
+(put 'c-buffer-is-cc-mode 'permanent-local t)
+\f
;; Regular expressions and other values which must be parameterized on
;; a per-language basis.
;; keywords introducing class definitions. language specific
(defconst c-C-class-key "\\(struct\\|union\\)")
(defconst c-C++-class-key "\\(class\\|struct\\|union\\)")
-(defconst c-IDL-class-key "\\(class\\|struct\\|union\\|interface\\)")
+(defconst c-IDL-class-key "\\(interface\\|struct\\|union\\|valuetype\\)")
(defconst c-C-extra-toplevel-key "\\(extern\\)")
(defconst c-C++-extra-toplevel-key "\\(extern\\|namespace\\)")
(defconst c-IDL-extra-toplevel-key "\\(module\\)")
(defvar c-extra-toplevel-key c-C-extra-toplevel-key)
(make-variable-buffer-local 'c-extra-toplevel-key)
+;; Keywords that can introduce bitfields in the languages that supports that.
+(defconst c-C-bitfield-key "\\(char\\|int\\|long\\|signed\\|unsigned\\)")
+
+(defvar c-bitfield-key nil)
+(make-variable-buffer-local 'c-bitfield-key)
+
\f
;; regexp describing access protection clauses. language specific
(defvar c-access-key nil)
(make-variable-buffer-local 'c-access-key)
(defconst c-C++-access-key (concat c-protection-key "[ \t]*:"))
+(defconst c-IDL-access-key nil)
(defconst c-ObjC-access-key (concat "@" c-protection-key))
(defconst c-Java-access-key nil)
(defconst c-Pike-access-key nil)
;; keywords introducing conditional blocks
(defconst c-C-conditional-key nil)
(defconst c-C++-conditional-key nil)
+(defconst c-IDL-conditional-key nil)
+(defconst c-ObjC-conditional-key nil)
(defconst c-Java-conditional-key nil)
(defconst c-Pike-conditional-key nil)
(back "\\)\\b[^_]"))
(setq c-C-conditional-key (concat front all-kws back)
c-C++-conditional-key (concat front all-kws exc-kws back)
+ ;; c-IDL-conditional-key is nil.
+ c-ObjC-conditional-key c-C-conditional-key
c-Java-conditional-key (concat front all-kws exc-kws thr-kws back)
c-Pike-conditional-key (concat front all-kws "\\|foreach" back)))
\f
;; comment starter definitions for various languages. language specific
(defconst c-C++-comment-start-regexp "/[/*]")
+(defconst c-C-comment-start-regexp c-C++-comment-start-regexp)
+(defconst c-IDL-comment-start-regexp c-C++-comment-start-regexp)
+(defconst c-ObjC-comment-start-regexp c-C++-comment-start-regexp)
+(defconst c-Pike-comment-start-regexp c-C++-comment-start-regexp)
;; We need to match all 3 Java style comments
;; 1) Traditional C block; 2) javadoc /** ...; 3) C++ style
(defconst c-Java-comment-start-regexp "/\\(/\\|[*][*]?\\)")
;; Regexp describing Javadoc markup that always starts paragraphs.
(defconst c-Java-javadoc-paragraph-start
- "@\\(author\\|exception\\|param\\|return\\|see\\|version\\)")
+ "@\\(author\\|exception\\|param\\|return\\|see\\|throws\\|version\\)")
;; Regexp that starts lambda constructs.
(defvar c-lambda-key nil)
;; Common initializations for all modes.
;; these variables should always be buffer local; they do not affect
;; indentation style.
- (make-local-variable 'paragraph-start)
- (make-local-variable 'paragraph-separate)
- (make-local-variable 'paragraph-ignore-fill-prefix)
(make-local-variable 'require-final-newline)
(make-local-variable 'parse-sexp-ignore-comments)
(make-local-variable 'indent-line-function)
(make-local-variable 'indent-region-function)
+ (make-local-variable 'outline-regexp)
+ (make-local-variable 'outline-level)
+ (make-local-variable 'normal-auto-fill-function)
(make-local-variable 'comment-start)
(make-local-variable 'comment-end)
(make-local-variable 'comment-column)
(make-local-variable 'comment-start-skip)
(make-local-variable 'comment-multi-line)
- (make-local-variable 'outline-regexp)
- (make-local-variable 'outline-level)
- (make-local-variable 'adaptive-fill-regexp)
+ (make-local-variable 'paragraph-start)
+ (make-local-variable 'paragraph-separate)
+ (make-local-variable 'paragraph-ignore-fill-prefix)
(make-local-variable 'adaptive-fill-mode)
+ (make-local-variable 'adaptive-fill-regexp)
(make-local-variable 'imenu-generic-expression) ;set in the mode functions
;; X/Emacs 20 only
(and (boundp 'comment-line-break-function)
- (make-local-variable 'comment-line-break-function))
- ;; Emacs 19.30 and beyond only, AFAIK
- (if (boundp 'fill-paragraph-function)
- (progn
- (make-local-variable 'fill-paragraph-function)
- (setq fill-paragraph-function 'c-fill-paragraph)))
+ (progn
+ (make-local-variable 'comment-line-break-function)
+ (setq comment-line-break-function
+ 'c-indent-new-comment-line)))
;; now set their values
- (setq paragraph-start (concat page-delimiter "\\|$")
- paragraph-separate paragraph-start
- paragraph-ignore-fill-prefix t
- require-final-newline t
+ (setq require-final-newline t
parse-sexp-ignore-comments t
indent-line-function 'c-indent-line
indent-region-function 'c-indent-region
outline-regexp "[^#\n\^M]"
outline-level 'c-outline-level
+ normal-auto-fill-function 'c-do-auto-fill
comment-column 32
- comment-start-skip "/\\*+ *\\|// *"
- comment-multi-line nil
- comment-line-break-function 'c-comment-line-break-function
- adaptive-fill-regexp nil
- adaptive-fill-mode nil)
+ comment-start-skip "/\\*+ *\\|//+ *"
+ comment-multi-line t)
+ ;; now set the mode style based on c-default-style
+ (let ((style (if (stringp c-default-style)
+ (if (c-major-mode-is 'java-mode)
+ "java"
+ c-default-style)
+ (or (cdr (assq major-mode c-default-style))
+ (cdr (assq 'other c-default-style))
+ "gnu"))))
+ ;; Override style variables if `c-old-style-variable-behavior' is
+ ;; set. Also override if we are using global style variables,
+ ;; have already initialized a style once, and are switching to a
+ ;; different style. (It's doubtful whether this is desirable, but
+ ;; the whole situation with nonlocal style variables is a bit
+ ;; awkward. It's at least the most compatible way with the old
+ ;; style init procedure.)
+ (c-set-style style (not (or c-old-style-variable-behavior
+ (and (not c-style-variables-are-local-p)
+ c-indentation-style
+ (not (string-equal c-indentation-style
+ style)))))))
+ ;; Fix things up for paragraph recognition and filling inside
+ ;; comments by using c-comment-prefix-regexp in the relevant places.
+ ;; We use adaptive filling for this to make it possible to use
+ ;; filladapt or some other fancy package.
+ (let ((comment-line-prefix
+ (concat "[ \t]*\\(" c-comment-prefix-regexp "\\)?[ \t]*")))
+ (setq paragraph-start (concat comment-line-prefix "$\\|"
+ page-delimiter)
+ paragraph-separate paragraph-start
+ paragraph-ignore-fill-prefix t
+ adaptive-fill-mode t
+ adaptive-fill-regexp
+ (concat comment-line-prefix
+ (if adaptive-fill-regexp
+ (concat "\\(" adaptive-fill-regexp "\\)")
+ "")))
+ (when (boundp 'adaptive-fill-first-line-regexp)
+ ;; XEmacs (20.x) adaptive fill mode doesn't have this.
+ (make-local-variable 'adaptive-fill-first-line-regexp)
+ (setq adaptive-fill-first-line-regexp
+ (concat "\\`" comment-line-prefix
+ ;; Maybe we should incorporate the old value here,
+ ;; but then we have to do all sorts of kludges to
+ ;; deal with the \` and \' it probably contains.
+ "\\'"))))
;; we have to do something special for c-offsets-alist so that the
;; buffer local value has its own alist structure.
(setq c-offsets-alist (copy-alist c-offsets-alist))
(setq minor-mode-alist
(cons '(c-auto-hungry-string c-auto-hungry-string)
minor-mode-alist)))
- ;; now set the mode style based on c-default-style
- (c-set-style (if (stringp c-default-style)
- (if (c-major-mode-is 'java-mode)
- "java"
- c-default-style)
- (or (cdr (assq major-mode c-default-style))
- (cdr (assq 'other c-default-style))
- "gnu")))
)
;; backward-kill-word.
(define-key c-mode-base-map [(control meta h)] 'c-mark-function)
(define-key c-mode-base-map "\e\C-q" 'c-indent-exp)
- (define-key c-mode-base-map "\ea" 'c-beginning-of-statement)
- (define-key c-mode-base-map "\ee" 'c-end-of-statement)
+ (substitute-key-definition 'backward-sentence
+ 'c-beginning-of-statement
+ c-mode-base-map global-map)
+ (substitute-key-definition 'forward-sentence
+ 'c-end-of-statement
+ c-mode-base-map global-map)
+ (substitute-key-definition 'indent-new-comment-line
+ 'c-indent-new-comment-line
+ c-mode-base-map global-map)
;; RMS says don't make these the default.
;; (define-key c-mode-base-map "\e\C-a" 'c-beginning-of-defun)
;; (define-key c-mode-base-map "\e\C-e" 'c-end-of-defun)
(define-key c-mode-base-map "\C-c\C-n" 'c-forward-conditional)
(define-key c-mode-base-map "\C-c\C-p" 'c-backward-conditional)
(define-key c-mode-base-map "\C-c\C-u" 'c-up-conditional)
- (define-key c-mode-base-map "\t" 'c-indent-command)
+ (substitute-key-definition 'indent-for-tab-command
+ 'c-indent-command
+ c-mode-base-map global-map)
+ ;; It doesn't suffice to put c-fill-paragraph on
+ ;; fill-paragraph-function due to the way it works.
+ (substitute-key-definition 'fill-paragraph 'c-fill-paragraph
+ c-mode-base-map global-map)
+ ;; In XEmacs the default fill function is called
+ ;; fill-paragraph-or-region.
+ (substitute-key-definition 'fill-paragraph-or-region 'c-fill-paragraph
+ c-mode-base-map global-map)
;; Caution! Enter here at your own risk. We are trying to support
;; several behaviors and it gets disgusting. :-(
;;
- ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
- ;; backwards deletion behavior to DEL, which both Delete and
- ;; Backspace get translated to. There's no way to separate this
- ;; behavior in a clean way, so deal with it! Besides, it's been
- ;; this way since the dawn of BOCM.
- (if (not (boundp 'delete-key-deletes-forward))
- (define-key c-mode-base-map "\177" 'c-electric-backspace)
- ;; However, XEmacs 20 actually achieved enlightenment. It is
- ;; possible to sanely define both backward and forward deletion
- ;; behavior under X separately (TTYs are forever beyond hope, but
- ;; who cares? XEmacs 20 does the right thing with these too).
- (define-key c-mode-base-map [delete] 'c-electric-delete)
- (define-key c-mode-base-map [backspace] 'c-electric-backspace))
+ (if (boundp 'delete-key-deletes-forward)
+ (progn
+ ;; In XEmacs 20 it is possible to sanely define both backward
+ ;; and forward deletion behavior under X separately (TTYs are
+ ;; forever beyond hope, but who cares? XEmacs 20 does the
+ ;; right thing with these too).
+ (define-key c-mode-base-map [delete] 'c-electric-delete)
+ (define-key c-mode-base-map [backspace] 'c-electric-backspace))
+ ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
+ ;; backwards deletion behavior to DEL, which both Delete and
+ ;; Backspace get translated to. There's no way to separate this
+ ;; behavior in a clean way, so deal with it! Besides, it's been
+ ;; this way since the dawn of BOCM.
+ (define-key c-mode-base-map "\177" 'c-electric-backspace))
;; these are new keybindings, with no counterpart to BOCM
(define-key c-mode-base-map "," 'c-electric-semi&comma)
(define-key c-mode-base-map "*" 'c-electric-star)
;;(define-key c-mode-base-map "\C-c\C-v" 'c-version)
)
-;; menu support for both XEmacs and Emacs. If you don't have easymenu
-;; with your version of Emacs, you are incompatible!
-(require 'easymenu)
-
(defvar c-c-menu nil)
(defvar c-c++-menu nil)
(defvar c-objc-menu nil)
;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
)
+(defvar c++-template-syntax-table nil
+ "A variant of `c++-mode-syntax-table' that defines `<' and `>' as
+parenthesis characters. Used temporarily when template argument lists
+are parsed.")
+(if c++-template-syntax-table
+ ()
+ (setq c++-template-syntax-table
+ (copy-syntax-table c++-mode-syntax-table))
+ (modify-syntax-entry ?< "(>" c++-template-syntax-table)
+ (modify-syntax-entry ?> ")<" c++-template-syntax-table))
+
(easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands"
(c-mode-menu "C++"))
;;; cc-menus.el --- imenu support for CC Mode
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
-;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-;; Pull in Imenu when compiling, if it exists
(eval-when-compile
+ (let ((load-path
+ (if (and (boundp 'byte-compile-current-file)
+ (stringp byte-compile-current-file))
+ (cons (file-name-directory byte-compile-current-file)
+ load-path)
+ load-path)))
+ (load "cc-defs" nil t)))
+
+;; Dummy definitions to shut up the compiler in case imenu doesn't exist.
+(defvar imenu-generic-expression)
+(defvar imenu-case-fold-search)
+(or (fboundp 'imenu-progress-message)
+ (defun imenu-progress-message (&rest args) nil))
+
+;; Try to pull in imenu.
+(eval-and-compile
(condition-case nil
(require 'imenu)
(error nil)))
A sample value might look like: `\\(_P\\|_PROTO\\)'.")
(defvar cc-imenu-c++-generic-expression
- (`
- (
+ `(
;; Try to match ::operator definitions first. Otherwise `X::operator new ()'
;; will be incorrectly recognised as function `new ()' because the regexps
;; work by backtracking from the end of the definition.
(nil
- (,
- (concat
+ ,(concat
"^\\<.*"
"[^a-zA-Z0-9_:<>~]" ; match any non-identifier char
; (note: this can be `\n')
; the parentheses surrounding
; the parameters. e.g.:
; `int foo(int a=bar()) {...}'
- )) 1)
+ ) 1)
;; Special case to match a line like `main() {}'
;; e.g. no return type, not even on the previous line.
(nil
- (,
- (concat
+ ,(concat
"^"
"\\([a-zA-Z_][a-zA-Z0-9_:<>~]*\\)" ; match function name
"[ \t]*(" ; see above, BUT
"[ \t]*\\([^ \t(*][^)]*\\)?)" ; the arg list must not start
"[ \t]*[^ \t;(]" ; with an asterisk or parentheses
- )) 1)
+ ) 1)
;; General function name regexp
(nil
- (,
- (concat
- "^\\<.*" ; line MUST start with word char
+ ,(concat
+ "^\\<" ; line MUST start with word char
+ "[^()]*" ; no parentheses before
"[^a-zA-Z0-9_:<>~]" ; match any non-identifier char
"\\([a-zA-Z_][a-zA-Z0-9_:<>~]*\\)" ; match function name
"[ \t]*(" ; see above, BUT
"[ \t]*\\([^ \t(*][^)]*\\)?)" ; the arg list must not start
"[ \t]*[^ \t;(]" ; with an asterisk or parentheses
- )) 1)
+ ) 1)
;; Special case for definitions using phony prototype macros like:
;; `int main _PROTO( (int argc,char *argv[]) )'.
;; This case is only included if cc-imenu-c-prototype-macro-regexp is set.
;; Only supported in c-code, so no `:<>~' chars in function name!
- (,@ (if cc-imenu-c-prototype-macro-regexp
- (` ((nil
- (,
- (concat
+ ,@(if cc-imenu-c-prototype-macro-regexp
+ `((nil
+ ,(concat
"^\\<.*" ; line MUST start with word char
"[^a-zA-Z0-9_]" ; match any non-identifier char
"\\([a-zA-Z_][a-zA-Z0-9_]*\\)" ; match function name
cc-imenu-c-prototype-macro-regexp
"[ \t]*(" ; ws followed by first paren.
"[ \t]*([^)]*)[ \t]*)[ \t]*[^ \t;]" ; see above
- )) 1)))))
+ ) 1)))
;; Class definitions
("Class"
- (, (concat
+ ,(concat
"^" ; beginning of line is required
"\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a `template <...>'
"class[ \t]+"
"[a-zA-Z0-9_]+" ; class name
"\\(<[^>]+>\\)?" ; possibly explicitely specialized
"\\)"
- "[ \t]*[:{]"
- )) 2)))
+ "[ \t\n]*[:{]"
+ ) 2))
"Imenu generic expression for C++ mode. See `imenu-generic-expression'.")
(defvar cc-imenu-c-generic-expression
"Imenu generic expression for C mode. See `imenu-generic-expression'.")
(defvar cc-imenu-java-generic-expression
- (`
- ((nil
- (,
- (concat
+ `((nil
+ ,(concat
"^\\([ \t]\\)*"
- "\\([A-Za-z0-9_-]+[ \t]+\\)?" ; type specs; there can be
- "\\([A-Za-z0-9_-]+[ \t]+\\)?" ; more than 3 tokens, right?
- "\\([A-Za-z0-9_-]+[ \t]*[[]?[]]?\\)"
+ "\\([.A-Za-z0-9_-]+[ \t]+\\)?" ; type specs; there can be
+ "\\([.A-Za-z0-9_-]+[ \t]+\\)?" ; more than 3 tokens, right?
+ "\\([.A-Za-z0-9_-]+[ \t]*[[]?[]]?\\)"
"\\([ \t]\\)"
"\\([A-Za-z0-9_-]+\\)" ; the string we want to get
"\\([ \t]*\\)+("
- "[][a-zA-Z,_1-9\n \t]*" ; arguments
+ "[][a-zA-Z,_1-9\n \t]*" ; arguments
")[ \t]*"
; "[^;(]"
"[,a-zA-Z_1-9\n \t]*{"
- )) 6)))
+ ) 6))
"Imenu generic expression for Java mode. See `imenu-generic-expression'.")
;; *Warning for cc-mode developers*
; ())
; FIXME: Please contribute one!
+(defun cc-imenu-init (mode-generic-expression)
+ (setq imenu-generic-expression mode-generic-expression
+ imenu-case-fold-search nil))
+
\f
(provide 'cc-menus)
;;; cc-menus.el ends here
;;; cc-mode.el --- major mode for editing C, C++, Objective-C, and Java code
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
-;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Created: a long, long, time ago. adapted from the original c-mode.el
;; Keywords: c languages oop
-(defconst c-version "5.25"
+(defconst c-version "5.26e"
"CC Mode version number.")
;; NOTE: Read the commentary below for the right way to submit bug reports!
;;; Code:
-\f
-(defvar c-buffer-is-cc-mode nil
- "Non-nil for all buffers with a `major-mode' derived from CC Mode.
-Otherwise, this variable is nil. I.e. this variable is non-nil for
-`c-mode', `c++-mode', `objc-mode', `java-mode', `idl-mode',
-`pike-mode', and any other non-CC Mode mode that calls
-`c-initialize-cc-mode' (e.g. `awk-mode').")
-(make-variable-buffer-local 'c-buffer-is-cc-mode)
-(put 'c-buffer-is-cc-mode 'permanent-local t)
-
-(eval-and-compile
- (require 'cc-defs))
+(eval-when-compile
+ (let ((load-path
+ ;; Try to make sure the source directory is at the front of
+ ;; load-path when we load cc-defs.
+ (if (and (boundp 'byte-compile-current-file)
+ (stringp byte-compile-current-file))
+ ;; byte-compile-current-file is set by the byte compiler
+ ;; to the full path to this file.
+ (cons (file-name-directory byte-compile-current-file)
+ load-path)
+ load-path)))
+ ;; Load our version of cc-defs unconditionally, since an older
+ ;; version might very well be dumped in or already loaded. This
+ ;; way we ensure that the code is compiled with the correct macros
+ ;; and defsubsts. The same problem affects the subpackages that's
+ ;; require'd below, but that doesn't harm the compiler; it can
+ ;; only cause some bogus warnings.
+ (load "cc-defs" nil t)))
+
+(require 'cc-defs) ; Not meaningless; this passes on require's from cc-defs.
(require 'cc-menus)
(require 'cc-vars)
-(require 'cc-engine)
+(require 'cc-styles)
(require 'cc-langs)
+(require 'cc-engine)
(require 'cc-align)
-(require 'cc-styles)
(require 'cc-cmds)
-
\f
;; Other modes and packages which depend on CC Mode should do the
;; following to make sure everything is loaded and available for their
(let ((initprop 'cc-mode-is-initialized)
c-initialization-ok)
(unless (get 'c-initialize-cc-mode initprop)
- (put 'c-initialize-cc-mode initprop t)
- (c-initialize-builtin-style)
(unwind-protect
(progn
+ (put 'c-initialize-cc-mode initprop t)
+ (c-initialize-builtin-style)
(run-hooks 'c-initialization-hook)
+ ;; Fix obsolete variables.
+ (if (boundp 'c-comment-continuation-stars)
+ (setq c-block-comment-prefix c-comment-continuation-stars))
(setq c-initialization-ok t))
;; Will try initialization hooks again if they failed.
- (unless c-initialization-ok
- (put 'c-initialize-cc-mode initprop nil))))
+ (put 'c-initialize-cc-mode initprop c-initialization-ok)))
))
\f
c-conditional-key c-C-conditional-key
c-class-key c-C-class-key
c-baseclass-key nil
- c-comment-start-regexp c-C++-comment-start-regexp
- imenu-generic-expression cc-imenu-c-generic-expression
- imenu-case-fold-search nil
+ c-comment-start-regexp c-C-comment-start-regexp
+ c-bitfield-key c-C-bitfield-key
)
+ (cc-imenu-init cc-imenu-c-generic-expression)
(run-hooks 'c-mode-common-hook)
(run-hooks 'c-mode-hook)
(c-update-modeline))
c-extra-toplevel-key c-C++-extra-toplevel-key
c-access-key c-C++-access-key
c-recognize-knr-p nil
- imenu-generic-expression cc-imenu-c++-generic-expression
- imenu-case-fold-search nil
+ c-bitfield-key c-C-bitfield-key
)
+ (cc-imenu-init cc-imenu-c++-generic-expression)
(run-hooks 'c-mode-common-hook)
(run-hooks 'c++-mode-hook)
(c-update-modeline))
(c-common-init)
(setq comment-start "// "
comment-end ""
- c-conditional-key c-C-conditional-key
- c-comment-start-regexp c-C++-comment-start-regexp
+ c-conditional-key c-ObjC-conditional-key
+ c-comment-start-regexp c-ObjC-comment-start-regexp
c-class-key c-ObjC-class-key
c-baseclass-key nil
c-access-key c-ObjC-access-key
c-method-key c-ObjC-method-key
- imenu-create-index-function 'cc-imenu-objc-function
- imenu-case-fold-search nil
)
+ (cc-imenu-init cc-imenu-objc-generic-expression)
(run-hooks 'c-mode-common-hook)
(run-hooks 'objc-mode-hook)
(c-update-modeline))
(c-common-init)
(setq comment-start "// "
comment-end ""
+ paragraph-start (concat paragraph-start
+ "\\("
+ c-Java-javadoc-paragraph-start
+ "\\|$\\)")
c-conditional-key c-Java-conditional-key
c-comment-start-regexp c-Java-comment-start-regexp
c-class-key c-Java-class-key
c-access-key c-Java-access-key
c-inexpr-class-key c-Java-inexpr-class-key
;defun-prompt-regexp c-Java-defun-prompt-regexp
- imenu-generic-expression cc-imenu-java-generic-expression
- imenu-case-fold-search nil
)
+ (cc-imenu-init cc-imenu-java-generic-expression)
(run-hooks 'c-mode-common-hook)
(run-hooks 'java-mode-hook)
(c-update-modeline))
(c-common-init)
(setq comment-start "// "
comment-end ""
- c-conditional-key c-C++-conditional-key
- c-comment-start-regexp c-C++-comment-start-regexp
+ c-conditional-key c-IDL-conditional-key
+ c-comment-start-regexp c-IDL-comment-start-regexp
c-class-key c-IDL-class-key
+ c-method-key nil
+ c-baseclass-key nil
c-extra-toplevel-key c-IDL-extra-toplevel-key
- c-access-key c-C++-access-key
+ c-access-key c-IDL-access-key
c-recognize-knr-p nil
-;; imenu-generic-expression cc-imenu-c++-generic-expression
-;; imenu-case-fold-search nil
)
+ ;;(cc-imenu-init cc-imenu-idl-generic-expression) ;FIXME
(run-hooks 'c-mode-common-hook)
(run-hooks 'idl-mode-hook)
(c-update-modeline))
(setq comment-start "// "
comment-end ""
c-conditional-key c-Pike-conditional-key
+ c-comment-start-regexp c-Pike-comment-start-regexp
c-class-key c-Pike-class-key
c-method-key nil
c-baseclass-key nil
c-lambda-key c-Pike-lambda-key
c-inexpr-block-key c-Pike-inexpr-block-key
c-special-brace-lists c-Pike-special-brace-lists
- ;imenu-generic-expression cc-imenu-java-generic-expression ;FIXME
- ;imenu-case-fold-search nil ;FIXME
)
+ ;;(cc-imenu-init cc-imenu-pike-generic-expression) ;FIXME
(run-hooks 'c-mode-common-hook)
(run-hooks 'pike-mode-hook)
(c-update-modeline))
+\f
+(defun c-setup-filladapt ()
+ "Convenience function to configure Kyle E. Jones' Filladapt mode for
+CC Mode by making sure the proper entries are present on
+`filladapt-token-table', `filladapt-token-match-table', and
+`filladapt-token-conversion-table'. This is intended to be used on
+`c-mode-common-hook' or similar."
+ ;; This function is intended to be used explicitly by the end user
+ ;; only.
+ ;;
+ ;; The default configuration already handles C++ comments, but we
+ ;; need to add handling of C block comments. A new filladapt token
+ ;; `c-comment' is added for that.
+ (let (p)
+ (setq p filladapt-token-table)
+ (while (and p (not (eq (car-safe (cdr-safe (car-safe p))) 'c-comment)))
+ (setq p (cdr-safe p)))
+ (if p
+ (setcar (car p) c-comment-prefix-regexp)
+ (setq filladapt-token-table
+ (append (list (car filladapt-token-table)
+ (list c-comment-prefix-regexp 'c-comment))
+ (cdr filladapt-token-table)))))
+ (unless (assq 'c-comment filladapt-token-match-table)
+ (setq filladapt-token-match-table
+ (append '((c-comment c-comment))
+ filladapt-token-match-table)))
+ (unless (assq 'c-comment filladapt-token-conversion-table)
+ (setq filladapt-token-conversion-table
+ (append '((c-comment . exact))
+ filladapt-token-conversion-table))))
+
\f
;; bug reporting
((eq major-mode 'c-mode) "C")
((eq major-mode 'objc-mode) "ObjC")
((eq major-mode 'java-mode) "Java")
+ ((eq major-mode 'idl-mode) "IDL")
((eq major-mode 'pike-mode) "Pike")
)
")")
- (let ((vars (list
+ (let ((vars (append
;; report only the vars that affect indentation
- 'c-basic-offset
- 'c-offsets-alist
- 'c-cleanup-list
- 'c-comment-only-line-offset
- 'c-backslash-column
- 'c-delete-function
- 'c-electric-pound-behavior
- 'c-hanging-braces-alist
- 'c-hanging-colons-alist
- 'c-hanging-comment-starter-p
- 'c-hanging-comment-ender-p
- 'c-indent-comments-syntactically-p
- 'c-tab-always-indent
- 'c-comment-continuation-stars
- 'c-label-minimum-indentation
- 'defun-prompt-regexp
- 'tab-width
- 'comment-column
- ;; A brain-damaged XEmacs only variable that, if
- ;; set to nil can cause all kinds of chaos.
- 'signal-error-on-buffer-boundary
- )))
- (if (not (boundp 'defun-prompt-regexp))
- (delq 'defun-prompt-regexp vars)
- vars))
+ c-style-variables
+ '(c-delete-function
+ c-electric-pound-behavior
+ c-indent-comments-syntactically-p
+ c-tab-always-indent
+ defun-prompt-regexp
+ tab-width
+ comment-column
+ parse-sexp-ignore-comments
+ ;; A brain-damaged XEmacs only variable that, if
+ ;; set to nil can cause all kinds of chaos.
+ signal-error-on-buffer-boundary
+ ;; Variables that affect line breaking and comments.
+ auto-fill-mode
+ filladapt-mode
+ comment-multi-line
+ comment-start-skip
+ fill-prefix
+ paragraph-start
+ adaptive-fill-mode
+ adaptive-fill-regexp)
+ nil)))
+ (delq 'c-special-indent-hook vars)
+ (unless (boundp 'defun-prompt-regexp)
+ (delq 'defun-prompt-regexp vars))
+ (unless (boundp 'filladapt-mode)
+ (delq 'filladapt-mode vars))
+ vars)
(function
(lambda ()
(insert
;;; cc-styles.el --- support for styles in CC Mode
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
-;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-
-;; explicit compile-time dependencies
(eval-when-compile
- (require 'cc-defs))
+ (let ((load-path
+ (if (and (boundp 'byte-compile-current-file)
+ (stringp byte-compile-current-file))
+ (cons (file-name-directory byte-compile-current-file)
+ load-path)
+ load-path)))
+ (load "cc-defs" nil t)))
+(require 'cc-vars)
+
\f
;; Warning: don't eval-defun this constant or you'll break style inheritance.
(inline-open . 0)
))
(c-special-indent-hook . c-gnu-impose-minimum)
- (c-comment-continuation-stars . "")
- (c-hanging-comment-ender-p . t)
+ (c-block-comment-prefix . "")
)
("k&r"
(c-basic-offset . 5)
(substatement-open . 0)
(label . 0)
(statement-cont . +)
+ (inline-open . 0)
+ (inexpr-class . 0)
))
)
("stroustrup"
("whitesmith"
(c-basic-offset . 4)
(c-comment-only-line-offset . 0)
- (c-offsets-alist . ((statement-block-intro . +)
- (knr-argdecl-intro . +)
- (substatement-open . 0)
+ (c-offsets-alist . ((knr-argdecl-intro . +)
(label . 0)
(statement-cont . +)
+ (substatement-open . +)
+ (block-open . +)
+ (statement-block-intro . c-lineup-whitesmith-in-block)
+ (block-close . c-lineup-whitesmith-in-block)
+ (inline-open . +)
+ (defun-open . +)
+ (defun-block-intro . c-lineup-whitesmith-in-block)
+ (defun-close . c-lineup-whitesmith-in-block)
+ (brace-list-open . +)
+ (brace-list-intro . c-lineup-whitesmith-in-block)
+ (brace-entry-open . c-indent-multi-line-block)
+ (brace-list-close . c-lineup-whitesmith-in-block)
+ (class-open . +)
+ (inclass . c-lineup-whitesmith-in-block)
+ (class-close . +)
+ (inexpr-class . 0)
+ (extern-lang-open . +)
+ (inextern-lang . c-lineup-whitesmith-in-block)
+ (extern-lang-close . +)
+ (namespace-open . +)
+ (innamespace . c-lineup-whitesmith-in-block)
+ (namespace-close . +)
))
-
)
("ellemtel"
(c-basic-offset . 3)
)
("python"
(indent-tabs-mode . t)
- (fill-column . 72)
+ (fill-column . 78)
(c-basic-offset . 8)
(c-offsets-alist . ((substatement-open . 0)
(inextern-lang . 0)
(substatement-open after)
(block-close . c-snug-do-while)
))
- (c-comment-continuation-stars . "")
- (c-hanging-comment-ender-p . nil)
- (fill-column . 78)
+ (c-block-comment-prefix . "")
)
("java"
(c-basic-offset . 4)
(c-comment-only-line-offset . (0 . 0))
;; the following preserves Javadoc starter lines
- (c-hanging-comment-starter-p . nil)
(c-offsets-alist . ((inline-open . 0)
(topmost-intro-cont . +)
(statement-block-intro . +)
(knr-argdecl-intro . 5)
(substatement-open . +)
- (label . 0)
+ (label . +)
(statement-case-open . +)
(statement-cont . +)
(arglist-intro . c-lineup-arglist-intro-after-paren)
(inher-cont . c-lineup-java-inher)
(func-decl-cont . c-lineup-java-throws)
))
-
)
)
"Styles of indentation.
Optional BASE-STYLE if present, is a string and must follow
STYLE-STRING. BASE-STYLE names a style that this style inherits from.
-By default, all styles inherit from the \"cc-mode\" style, which is
+By default, all styles inherit from the \"user\" style, which is
computed at run time. Style loops generate errors.
Two variables are treated specially. When VARIABLE is
modify existing styles -- you should create a new style that inherits
the existing style.")
+
\f
;; Functions that manipulate styles
-(defun c-set-style-1 (conscell)
+(defun c-set-style-1 (conscell dont-override)
;; Set the style for one variable
(let ((attr (car conscell))
(val (cdr conscell)))
(lambda (langentry)
(let ((langelem (car langentry))
(offset (cdr langentry)))
- (c-set-offset langelem offset)
+ (unless (and dont-override
+ (assq langelem c-offsets-alist))
+ (c-set-offset langelem offset))
)))
- val))
+ (if dont-override (reverse val) val)))
;; second special variable
((eq attr 'c-special-indent-hook)
- (if (listp val)
- (while val
- (add-hook 'c-special-indent-hook (car val))
- (setq val (cdr val)))
- (add-hook 'c-special-indent-hook val)))
+ (let ((add-func (if dont-override
+ (lambda (func)
+ (unless (memq func c-special-indent-hook)
+ (add-hook 'c-special-indent-hook func t)))
+ (lambda (func)
+ (add-hook 'c-special-indent-hook func)))))
+ (if (listp val)
+ (mapcar add-func (if dont-override (reverse val) val))
+ (funcall add-func val))))
;; all other variables
- (t (set attr val)))
+ (t (if (or (not dont-override)
+ (not (memq attr c-style-variables))
+ (eq (symbol-value attr) 'set-from-style))
+ (set attr val))))
))
-(defun c-set-style-2 (style basestyles)
- ;; Recursively set the base style. If no base style is given, the
- ;; default base style is "user" (a.k.a. "cc-mode") and the recursion
- ;; stops. Be sure to detect loops.
+(defun c-get-style-variables (style basestyles)
+ ;; Return all variables in a style by resolving inheritances.
(let ((vars (cdr (or (assoc (downcase style) c-style-alist)
(assoc (upcase style) c-style-alist)
(assoc style c-style-alist)
(error "Undefined style: %s" style)))))
- (if (not (string-equal style "user"))
- (let ((base (if (stringp (car vars))
- (prog1
- (downcase (car vars))
- (setq vars (cdr vars)))
- "user")))
- (if (memq base basestyles)
- (error "Style loop detected: %s in %s" base basestyles))
- (c-set-style-2 base (cons base basestyles))))
- (mapcar 'c-set-style-1 vars)))
-
+ (if (string-equal style "user")
+ (copy-alist vars)
+ (let ((base (if (stringp (car vars))
+ (prog1
+ (downcase (car vars))
+ (setq vars (cdr vars)))
+ "user")))
+ (if (memq base basestyles)
+ (error "Style loop detected: %s in %s" base basestyles))
+ (nconc (c-get-style-variables base (cons base basestyles))
+ (copy-alist vars))))))
+
(defvar c-set-style-history nil)
;;;###autoload
-(defun c-set-style (stylename)
+(defun c-set-style (stylename &optional dont-override)
"Set CC Mode variables to use one of several different indentation styles.
STYLENAME is a string representing the desired style from the list of
styles described in the variable `c-style-alist'. See that variable
for details of setting up styles.
The variable `c-indentation-style' always contains the buffer's current
-style name."
+style name.
+
+If the optional argument DONT-OVERRIDE is non-nil, no style variables
+that already have values will be overridden. I.e. in the case of
+`c-offsets-alist', syntactic symbols will only be added, and in the
+case of all other style variables, only those set to `set-from-style'
+will be reassigned.
+
+Obviously, specifying DONT-OVERRIDE is useful mainly when the initial
+style is chosen for a CC Mode buffer by a major mode. Since this is
+done internally by CC Mode, there's hardly ever a reason to use it."
(interactive (list (let ((completion-ignore-case t)
(prompt (format "Which %s indentation style? "
mode-name)))
(cons c-indentation-style 0)
'c-set-style-history))))
(c-initialize-builtin-style)
- (c-set-style-2 stylename nil)
+ (let ((vars (c-get-style-variables stylename nil)))
+ (mapcar (lambda (elem)
+ (c-set-style-1 elem dont-override))
+ ;; Need to go through the variables backwards when we
+ ;; don't override.
+ (if dont-override (nreverse vars) vars)))
(setq c-indentation-style stylename)
(c-keep-region-active))
\f
-(defconst c-offsets-alist
- '((string . c-lineup-dont-change)
- (c . c-lineup-C-comments)
- (defun-open . 0)
- (defun-close . 0)
- (defun-block-intro . +)
- (class-open . 0)
- (class-close . 0)
- (inline-open . +)
- (inline-close . 0)
- (func-decl-cont . +)
- (knr-argdecl-intro . +)
- (knr-argdecl . 0)
- (topmost-intro . 0)
- (topmost-intro-cont . 0)
- (member-init-intro . +)
- (member-init-cont . 0)
- (inher-intro . +)
- (inher-cont . c-lineup-multi-inher)
- (block-open . 0)
- (block-close . 0)
- (brace-list-open . 0)
- (brace-list-close . 0)
- (brace-list-intro . +)
- (brace-list-entry . 0)
- (brace-entry-open . 0)
- (statement . 0)
- ;; some people might prefer
- ;;(statement . c-lineup-runin-statements)
- (statement-cont . +)
- ;; some people might prefer
- ;;(statement-cont . c-lineup-math)
- (statement-block-intro . +)
- (statement-case-intro . +)
- (statement-case-open . 0)
- (substatement . +)
- (substatement-open . +)
- (case-label . 0)
- (access-label . -)
- (label . 2)
- (do-while-closure . 0)
- (else-clause . 0)
- (catch-clause . 0)
- (comment-intro . c-lineup-comment)
- (arglist-intro . +)
- (arglist-cont . 0)
- (arglist-cont-nonempty . c-lineup-arglist)
- (arglist-close . +)
- (stream-op . c-lineup-streamop)
- (inclass . +)
- (cpp-macro . -1000)
- (cpp-macro-cont . c-lineup-dont-change)
- (friend . 0)
- (objc-method-intro . -1000)
- (objc-method-args-cont . c-lineup-ObjC-method-args)
- (objc-method-call-cont . c-lineup-ObjC-method-call)
- (extern-lang-open . 0)
- (extern-lang-close . 0)
- (inextern-lang . +)
- (namespace-open . 0)
- (namespace-close . 0)
- (innamespace . +)
- (template-args-cont . +)
- (inlambda . c-lineup-inexpr-block)
- (lambda-intro-cont . +)
- (inexpr-statement . 0)
- (inexpr-class . +)
- )
- "Association list of syntactic element symbols and indentation offsets.
-As described below, each cons cell in this list has the form:
-
- (SYNTACTIC-SYMBOL . OFFSET)
-
-When a line is indented, CC Mode first determines the syntactic
-context of the line by generating a list of symbols called syntactic
-elements. This list can contain more than one syntactic element and
-the global variable `c-syntactic-context' contains the context list
-for the line being indented. Each element in this list is actually a
-cons cell of the syntactic symbol and a buffer position. This buffer
-position is called the relative indent point for the line. Some
-syntactic symbols may not have a relative indent point associated with
-them.
-
-After the syntactic context list for a line is generated, CC Mode
-calculates the absolute indentation for the line by looking at each
-syntactic element in the list. First, it compares the syntactic
-element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it
-finds a match, it adds the OFFSET to the column of the relative indent
-point. The sum of this calculation for each element in the syntactic
-list is the absolute offset for line being indented.
-
-If the syntactic element does not match any in the `c-offsets-alist',
-an error is generated if `c-strict-syntax-p' is non-nil, otherwise the
-element is ignored.
-
-Actually, OFFSET can be an integer, a function, a variable, or one of
-the following symbols: `+', `-', `++', `--', `*', or `/'. These
-latter designate positive or negative multiples of `c-basic-offset',
-respectively: 1, -1, 2, -2, 0.5, and -0.5. If OFFSET is a function, it
-is called with a single argument containing the cons of the syntactic
-element symbol and the relative indent point. The function should
-return an integer offset.
-
-OFFSET can also be a list, in which case it is recursively evaluated
-using the semantics described above. The first element of the list to
-return a non-nil value succeeds. If none of the elements returns a
-non-nil value, then what happends depends on the value of
-`c-strict-syntax-p'. When `c-strict-syntax-p' is nil, then an offset
-of zero is used, otherwise an error is generated.
-
-Here is the current list of valid syntactic element symbols:
-
- string -- inside multi-line string
- c -- inside a multi-line C style block comment
- defun-open -- brace that opens a function definition
- defun-close -- brace that closes a function definition
- defun-block-intro -- the first line in a top-level defun
- class-open -- brace that opens a class definition
- class-close -- brace that closes a class definition
- inline-open -- brace that opens an in-class inline method
- inline-close -- brace that closes an in-class inline method
- func-decl-cont -- the region between a function definition's
- argument list and the function opening brace
- (excluding K&R argument declarations). In C, you
- cannot put anything but whitespace and comments
- between them; in C++ and Java, throws declarations
- and other things can appear in this context.
- knr-argdecl-intro -- first line of a K&R C argument declaration
- knr-argdecl -- subsequent lines in a K&R C argument declaration
- topmost-intro -- the first line in a topmost construct definition
- topmost-intro-cont -- topmost definition continuation lines
- member-init-intro -- first line in a member initialization list
- member-init-cont -- subsequent member initialization list lines
- inher-intro -- first line of a multiple inheritance list
- inher-cont -- subsequent multiple inheritance lines
- block-open -- statement block open brace
- block-close -- statement block close brace
- brace-list-open -- open brace of an enum or static array list
- brace-list-close -- close brace of an enum or static array list
- brace-list-intro -- first line in an enum or static array list
- brace-list-entry -- subsequent lines in an enum or static array list
- brace-entry-open -- subsequent lines in an enum or static array
- list that start with an open brace.
- statement -- a C (or like) statement
- statement-cont -- a continuation of a C (or like) statement
- statement-block-intro -- the first line in a new statement block
- statement-case-intro -- the first line in a case \"block\"
- statement-case-open -- the first line in a case block starting with brace
- substatement -- the first line after an if/while/for/do/else
- substatement-open -- the brace that opens a substatement block
- case-label -- a `case' or `default' label
- access-label -- C++ private/protected/public access label
- label -- any ordinary label
- do-while-closure -- the `while' that ends a do/while construct
- else-clause -- the `else' of an if/else construct
- catch-clause -- the `catch' or `finally' of a try/catch construct
- comment-intro -- a line containing only a comment introduction
- arglist-intro -- the first line in an argument list
- arglist-cont -- subsequent argument list lines when no
- arguments follow on the same line as the
- arglist opening paren
- arglist-cont-nonempty -- subsequent argument list lines when at
- least one argument follows on the same
- line as the arglist opening paren
- arglist-close -- the solo close paren of an argument list
- stream-op -- lines continuing a stream operator construct
- inclass -- the construct is nested inside a class definition
- cpp-macro -- the start of a C preprocessor macro definition
- cpp-macro-cont -- the second and subsequent lines in a
- multi-line C preprocessor macro definition
- friend -- a C++ friend declaration
- objc-method-intro -- the first line of an Objective-C method definition
- objc-method-args-cont -- lines continuing an Objective-C method definition
- objc-method-call-cont -- lines continuing an Objective-C method call
- extern-lang-open -- brace that opens an external language block
- extern-lang-close -- brace that closes an external language block
- inextern-lang -- analogous to `inclass' syntactic symbol,
- but used inside, e.g. extern \"C\" constructs
- namespace-open -- brace that opens a C++ namespace block
- namespace-close -- brace that closes a C++ namespace block
- innamespace -- analogous to `inextern-lang' syntactic
- symbol, but used inside C++ namespace constructs
- template-args-cont -- C++ template argument list continuations
- inlambda -- in the header or body of a lambda function
- lambda-intro-cont -- continuation of the header of a lambda function
- inexpr-statement -- the statement is inside an expression
- inexpr-class -- the class is inside an expression
-")
-
(defun c-evaluate-offset (offset langelem symbol)
;; offset can be a number, a function, a variable, a list, or one of
;; the symbols + or -
(goto-char relpos)
(current-column))
0)
- (c-evaluate-offset offset langelem symbol))
+ (or (and (numberp offset) offset)
+ (and (symbolp offset) (symbol-value offset))
+ 0))
))
+
\f
(defvar c-read-offset-history nil)
(defun c-read-offset (langelem)
;; read new offset value for LANGELEM from minibuffer. return a
;; legal value only
- (let* ((oldoff (cdr-safe (assq langelem c-offsets-alist)))
+ (let* ((oldoff (cdr-safe (or (assq langelem c-offsets-alist)
+ (assq langelem (get 'c-offsets-alist
+ 'c-stylevar-fallback)))))
(symname (symbol-name langelem))
(defstr (format "(default %s): " oldoff))
(errmsg (concat "Offset must be int, func, var, list, "
offset))
;;;###autoload
-(defun c-set-offset (symbol offset &optional add-p)
+(defun c-set-offset (symbol offset &optional ignored)
"Change the value of a syntactic element symbol in `c-offsets-alist'.
SYMBOL is the syntactic element symbol to change and OFFSET is the new
-offset for that syntactic element. Optional ADD says to add SYMBOL to
-`c-offsets-alist' if it doesn't already appear there."
+offset for that syntactic element. The optional argument is not used
+and exists only for compatibility reasons."
(interactive
(let* ((langelem
(intern (completing-read
(mapcar
#'(lambda (langelem)
(cons (format "%s" (car langelem)) nil))
- c-offsets-alist)
+ (get 'c-offsets-alist 'c-stylevar-fallback))
nil (not current-prefix-arg)
;; initial contents tries to be the last element
;; on the syntactic analysis list for the current
(offset (c-read-offset langelem)))
(list langelem offset current-prefix-arg)))
;; sanity check offset
- (or (eq offset '+)
- (eq offset '-)
- (eq offset '++)
- (eq offset '--)
- (eq offset '*)
- (eq offset '/)
- (integerp offset)
- (functionp offset)
- (listp offset)
- (boundp offset)
- (error "Offset must be int, func, var, list, or in [+,-,++,--,*,/]: %s"
- offset))
+ (unless (c-valid-offset offset)
+ (error "Offset must be int, func, var, list, or in [+,-,++,--,*,/]: %s"
+ offset))
(let ((entry (assq symbol c-offsets-alist)))
(if entry
(setcdr entry offset)
- (if add-p
+ (if (assq symbol (get 'c-offsets-alist 'c-stylevar-fallback))
(setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
- (error "%s is not a valid syntactic symbol." symbol))))
+ (error "%s is not a valid syntactic symbol" symbol))))
(c-keep-region-active))
-\f
-(defun c-copy-tree (tree)
- (if (consp tree)
- (cons (c-copy-tree (car tree))
- (c-copy-tree (cdr tree)))
- tree))
+\f
(defun c-initialize-builtin-style ()
;; Dynamically append the default value of most variables. This is
;; crucial because future c-set-style calls will always reset the
(or (assoc "cc-mode" c-style-alist)
(assoc "user" c-style-alist)
(progn
- (c-add-style "user"
- (mapcar
- (function
- (lambda (var)
- (let ((val (symbol-value var)))
- (cons var (c-copy-tree val)))))
- '(c-backslash-column
- c-basic-offset
- c-cleanup-list
- c-comment-only-line-offset
- c-electric-pound-behavior
- c-hanging-braces-alist
- c-hanging-colons-alist
- c-hanging-comment-starter-p
- c-hanging-comment-ender-p
- c-offsets-alist
- )))
- (c-add-style "cc-mode" '("user"))
- ))
+ (c-add-style
+ "user"
+ (mapcar
+ (lambda (var)
+ (let ((val (symbol-value var)))
+ (cons var
+ (cond ((eq var 'c-offsets-alist)
+ (mapcar
+ (lambda (langentry)
+ (setq langentry (or (assq (car langentry) val)
+ langentry))
+ (cons (car langentry)
+ (cdr langentry)))
+ (get var 'c-stylevar-fallback)))
+ ((eq var 'c-special-indent-hook)
+ val)
+ (t
+ (if (eq val 'set-from-style)
+ (get var 'c-stylevar-fallback)
+ val))))))
+ c-style-variables))
+ (c-add-style "cc-mode" '("user"))))
(if c-style-variables-are-local-p
(c-make-styles-buffer-local))))
-
(defun c-make-styles-buffer-local (&optional this-buf-only-p)
"Make all CC Mode style variables buffer local.
-If you edit primarily one style of C (or C++, Objective-C, Java) code,
-you probably want style variables to be global. This is the default.
+If you edit primarily one style of C (or C++, Objective-C, Java, etc)
+code, you probably want style variables to be global. This is the
+default.
-If you edit many different styles of C (or C++, Objective-C, Java) at
-the same time, you probably want the CC Mode style variables to be
-buffer local. If you do, then you will need to set any CC Mode style
-variables in a hook function (e.g. off of c-mode-common-hook), instead
-of at the top level of your ~/.emacs file.
+If you edit many different styles of C (or C++, Objective-C, Java,
+etc) at the same time, you probably want the CC Mode style variables
+to be buffer local. If you do, it's advicable to set any CC Mode
+style variables in a hook function (e.g. off of `c-mode-common-hook'),
+instead of at the top level of your ~/.emacs file.
This function makes all the CC Mode style variables buffer local.
Call it after CC Mode is loaded into your Emacs environment.
(let ((func (if this-buf-only-p
'make-local-variable
'make-variable-buffer-local))
- (varsyms '(c-offsets-alist
- c-basic-offset
- c-file-style
- c-file-offsets
- c-comment-only-line-offset
- c-cleanup-list
- c-hanging-braces-alist
- c-hanging-colons-alist
- c-hanging-comment-starter-p
- c-hanging-comment-ender-p
- c-backslash-column
- c-label-minimum-indentation
- c-indentation-style)))
+ (varsyms (cons 'c-indentation-style (copy-alist c-style-variables))))
+ (delq 'c-special-indent-hook varsyms)
(mapcar func varsyms)
;; Hooks must be handled specially
(if this-buf-only-p
(make-local-hook 'c-special-indent-hook)
- (make-variable-buffer-local 'c-special-indent-hook))
+ (make-variable-buffer-local 'c-special-indent-hook)
+ (setq c-style-variables-are-local-p t))
))
;;; cc-vars.el --- user customization variables for CC Mode
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
-;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
;; 1992-1997 Barry A. Warsaw
;; 1987 Dave Detlefs and Stewart Clamen
;; 1985 Richard M. Stallman
;; Boston, MA 02111-1307, USA.
(eval-when-compile
- (require 'cc-defs))
-
+ (let ((load-path
+ (if (and (boundp 'byte-compile-current-file)
+ (stringp byte-compile-current-file))
+ (cons (file-name-directory byte-compile-current-file)
+ load-path)
+ load-path)))
+ (load "cc-defs" nil t)))
(require 'custom)
+
+\f
+;;; Helpers
+
+;; This widget will show up in newer versions of the Custom library
+(or (get 'other 'widget-type)
+ (define-widget 'other 'sexp
+ "Matches everything, but doesn't let the user edit the value.
+Useful as last item in a `choice' widget."
+ :tag "Other"
+ :format "%t%n"
+ :value 'other))
+
+(define-widget 'c-const-symbol 'item
+ "An uneditable lisp symbol."
+ :value nil
+ :tag "Symbol"
+ :format "%t: %v\n%d"
+ :match (lambda (widget value) (symbolp value))
+ :value-to-internal
+ (lambda (widget value)
+ (let ((s (if (symbolp value)
+ (symbol-name value)
+ value))
+ (l (widget-get widget :size)))
+ (if l
+ (setq s (concat s (make-string (- l (length s)) ?\ ))))
+ s))
+ :value-to-external
+ (lambda (widget value)
+ (if (stringp value)
+ (intern (progn
+ (string-match "\\`[^ ]*" value)
+ (match-string 0 value)))
+ value)))
+
+(defvar c-style-variables
+ '(c-basic-offset c-comment-only-line-offset c-block-comment-prefix
+ c-comment-prefix-regexp c-cleanup-list c-hanging-braces-alist
+ c-hanging-colons-alist c-hanging-semi&comma-criteria c-backslash-column
+ c-special-indent-hook c-label-minimum-indentation c-offsets-alist)
+ "List of the style variables.")
+
+(defmacro defcustom-c-stylevar (name val doc &rest args)
+ "Defines a style variable."
+ (setq val (if (eq (car-safe val) 'quote)
+ (nth 1 val)
+ (eval val)))
+ `(progn
+ (put ',name 'c-stylevar-fallback ',val)
+ (defcustom ,name 'set-from-style
+ ,(concat doc "
+
+This is a style variable. Apart from the valid values described
+above, it can be set to the symbol `set-from-style'. In that case, it
+takes its value from the style system (see `c-default-style' and
+`c-styles-alist') when a CC Mode buffer is initialized. Otherwise,
+the value set here overrides the style system (there is a variable
+`c-old-style-variable-behavior' that changes this, though).")
+ ,@(plist-put
+ args ':type
+ `'(radio
+ (const :tag "Use style settings"
+ set-from-style)
+ ,(let ((type (eval (plist-get args ':type))))
+ (unless (consp type)
+ (setq type (list type)))
+ (unless (c-safe (plist-get (cdr type) ':value))
+ (setcdr type (append `(:value ,val)
+ (cdr type))))
+ (unless (c-safe (plist-get (cdr type) ':tag))
+ (setcdr type (append '(:tag "Override style settings")
+ (cdr type))))
+ type))))))
+
+(defun c-valid-offset (offset)
+ "Return non-nil iff OFFSET is a valid offset for a syntactic symbol.
+See `c-offsets-alist'."
+ (or (eq offset '+)
+ (eq offset '-)
+ (eq offset '++)
+ (eq offset '--)
+ (eq offset '*)
+ (eq offset '/)
+ (integerp offset)
+ (functionp offset)
+ (and (symbolp offset)
+ (or (boundp offset)
+ (fboundp offset)))
+ (progn
+ (while (and (consp offset)
+ (c-valid-offset (car offset)))
+ (setq offset (cdr offset)))
+ (null offset))))
+
+
\f
+;;; User variables
+
(defcustom c-strict-syntax-p nil
"*If non-nil, all syntactic symbols must be found in `c-offsets-alist'.
If the syntactic symbol for a particular line does not match a symbol
in the offsets alist, or if no non-nil offset value can be determined
for a symbol, an error is generated, otherwise no error is reported
-and the syntactic symbol is ignored."
+and the syntactic symbol is ignored.
+
+This variable is considered obsolete; it doesn't work well with lineup
+functions that return nil to support the feature of using lists on
+syntactic symbols in `c-offsets-alist'. Please keep it set to nil."
:type 'boolean
:group 'c)
:type 'boolean
:group 'c)
-(defcustom c-basic-offset 4
+(defcustom-c-stylevar c-basic-offset 4
"*Amount of basic offset used by + and - symbols in `c-offsets-alist'."
:type 'integer
:group 'c)
-;; This widget will show up in newer versions of the Custom library
-(or (get 'other 'widget-type)
- (define-widget 'other 'sexp
- "Matches everything, but doesn't let the user edit the value.
-Useful as last item in a `choice' widget."
- :tag "Other"
- :format "%t%n"
- :value 'other))
-
(defcustom c-tab-always-indent t
"*Controls the operation of the TAB key.
If t, hitting TAB always just indents the current line. If nil,
directives, but the line is always reindented.
Note: The value of `indent-tabs-mode' will determine whether a real
-tab character will be inserted, or the equivalent number of space.
+tab character will be inserted, or the equivalent number of spaces.
When inserting a tab, actually the function stored in the variable
`c-insert-tab-function' is called.
:type 'function
:group 'c)
-(defcustom c-comment-only-line-offset 0
+(defcustom-c-stylevar c-comment-only-line-offset 0
"*Extra offset for line which contains only the start of a comment.
Can contain an integer or a cons cell of the form:
Where NON-ANCHORED-OFFSET is the amount of offset given to
non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
the amount of offset to give column-zero anchored comment-only lines.
-Just an integer as value is equivalent to (<val> . -1000)."
- :type '(choice (integer :tag "Non-anchored offset")
+Just an integer as value is equivalent to (<val> . -1000).
+
+Note that this variable only has effect when the `c-lineup-comment'
+lineup function is used on the `comment-intro' syntactic symbol (the
+default)."
+ :type '(choice (integer :tag "Non-anchored offset" 0)
(cons :tag "Non-anchored & anchored offset"
:value (0 . 0)
:extra-offset 8
:group 'c)
(defcustom c-indent-comments-syntactically-p nil
- "*Specifies how comment-only lines should be indented.
+ "*Specifies how \\[indent-for-comment] should handle comment-only lines.
When this variable is non-nil, comment-only lines are indented
-according to syntactic analysis via `c-offsets-alist', even when
-\\[indent-for-comment] is used."
+according to syntactic analysis via `c-offsets-alist'. Otherwise, the
+comment is indented as if it was preceded by code. Note that this
+variable does not affect how the normal line indentation treats
+comment-only lines."
:type 'boolean
:group 'c)
-(defcustom c-comment-continuation-stars "* "
- "*Specifies the leader of continued block comments.
+(defcustom-c-stylevar c-block-comment-prefix
+ (if (boundp 'c-comment-continuation-stars)
+ c-comment-continuation-stars
+ "* ")
+ "*Specifies the line prefix of continued C-style block comments.
You should set this variable to the literal string that gets inserted
at the front of continued block style comment lines. This should
-either be the empty string, or some number of stars followed by a
-single space. Note that for line style comments, this variable is not
-used."
- :type '(choice (const :tag "Use old semantics" nil)
- string)
+either be the empty string, or some characters without preceding
+spaces. To adjust the alignment under the comment starter, put an
+appropriate value on the `c' syntactic symbol (see the
+`c-offsets-alist' variable).
+
+It's only used when a one-line block comment is broken into two or
+more lines for the first time; otherwise the appropriate prefix is
+adapted from the comment. This variable is not used for C++ line
+style comments."
+ :type 'string
+ :group 'c)
+
+(make-obsolete-variable 'c-comment-continuation-stars
+ 'c-block-comment-prefix)
+
+(defcustom-c-stylevar c-comment-prefix-regexp "//+\\|\\**"
+ "*Regexp to match the line prefix inside comments.
+This regexp is used to recognize the fill prefix inside comments for
+correct paragraph filling and other things.
+
+It should match the prefix used in both C++ style line comments and C
+style block comments, but it does not need to match a block comment
+starter. In other words, it should at least match \"//\" for line
+comments and the string in `c-block-comment-prefix', which is
+sometimes inserted by CC Mode inside block comments. It should not
+match any surrounding whitespace.
+
+Note that CC Mode modifies other variables from this one at mode
+initialization, so you might need to do \\[c-mode] (or whatever mode
+you're currently using) if you change it in a CC Mode buffer."
+ :type 'regexp
:group 'c)
-(defcustom c-cleanup-list '(scope-operator)
+(defcustom c-ignore-auto-fill '(string cpp code)
+ "*List of contexts in which automatic filling never occurs.
+If Auto Fill mode is active, it will be temporarily disabled if point
+is in any context on this list. It's e.g. useful to enable Auto Fill
+in comments only, but not in strings or normal code. The valid
+contexts are:
+
+ string -- inside a string or character literal
+ c -- inside a C style block comment
+ c++ -- inside a C++ style line comment
+ cpp -- inside a preprocessor directive
+ code -- anywhere else, i.e. in normal code"
+ :type '(set
+ :extra-offset 8
+ (const :tag "String literals" string)
+ (const :tag "C style block comments" c)
+ (const :tag "C++ style line comments" c++)
+ (const :tag "Preprocessor directives" cpp)
+ (const :tag "Normal code" code))
+ :group 'c)
+
+(defcustom-c-stylevar c-cleanup-list '(scope-operator)
"*List of various C/C++/ObjC constructs to \"clean up\".
These clean ups only take place when the auto-newline feature is
turned on, as evidenced by the `/a' or `/ah' appearing next to the
construct on a single line. This clean up
only takes place when there is nothing but
white space between the braces and the `else'.
- Clean up occurs when the open-brace after the
+ Clean up occurs when the open brace after the
`else' is typed.
brace-elseif-brace -- similar to brace-else-brace, but cleans up
`} else if (...) {' constructs. Clean up occurs
- both after the open parenthesis and after the
- open brace.
+ after the open parenthesis and the open brace.
brace-catch-brace -- similar to brace-elseif-brace, but cleans up
`} catch (...) {' constructs.
empty-defun-braces -- cleans up empty defun braces by placing the
(const :tag "Put `} else if (...) {' on one line" brace-elseif-brace)
(const :tag "Put `} catch (...) {' on one line" brace-catch-brace)
(const :tag "Put empty defun braces on one line" empty-defun-braces)
+ (const :tag "Put `};' ending defuns on one line" defun-close-semi)
(const :tag "Put `},' in aggregates on one line" list-close-comma)
(const :tag "Put C++ style `::' on one line" scope-operator))
:group 'c)
-(defcustom c-hanging-braces-alist '((brace-list-open)
- (brace-entry-open)
- (substatement-open after)
- (block-close . c-snug-do-while)
- (extern-lang-open after)
- (inexpr-class-open after)
- (inexpr-class-close before)
- )
- "*Controls the insertion of newlines before and after braces.
-This variable contains an association list with elements of the
-following form: (SYNTACTIC-SYMBOL . ACTION).
+(defcustom-c-stylevar c-hanging-braces-alist '((brace-list-open)
+ (brace-entry-open)
+ (substatement-open after)
+ (block-close . c-snug-do-while)
+ (extern-lang-open after)
+ (inexpr-class-open after)
+ (inexpr-class-close before))
+ "*Controls the insertion of newlines before and after braces
+when the auto-newline feature is active. This variable contains an
+association list with elements of the following form:
+\(SYNTACTIC-SYMBOL . ACTION).
When a brace (either opening or closing) is inserted, the syntactic
context it defines is looked up in this list, and if found, the
class-close, inline-open, inline-close, block-open, block-close,
substatement-open, statement-case-open, extern-lang-open,
extern-lang-close, brace-list-open, brace-list-close,
-brace-list-intro, brace-entry-open, inexpr-class-open, or
-inexpr-class-close. See `c-offsets-alist' for details, except for
-inexpr-class-open and inexpr-class-close, which doesn't have any
-corresponding symbols there. Those two symbols are used for the
-opening and closing braces, respectively, of anonymous inner classes
-in Java.
+brace-list-intro, brace-entry-open, namespace-open, namespace-close,
+inexpr-class-open, or inexpr-class-close. See `c-offsets-alist' for
+details, except for inexpr-class-open and inexpr-class-close, which
+doesn't have any corresponding symbols there. Those two symbols are
+used for the opening and closing braces, respectively, of anonymous
+inner classes in Java.
ACTION can be either a function symbol or a list containing any
combination of the symbols `before' or `after'. If the list is empty,
described in the preceding paragraph. Note that during the call to
the function, the variable `c-syntactic-context' is set to the entire
syntactic context for the brace line."
- :type '(repeat
- (cons :format "%v"
- (choice :tag "Syntax"
- (const defun-open) (const defun-close)
- (const class-open) (const class-close)
- (const inline-open) (const inline-close)
- (const block-open) (const block-close)
- (const substatement-open) (const statement-case-open)
- (const extern-lang-open) (const extern-lang-close)
- (const brace-list-open) (const brace-list-close)
- (const brace-list-intro) (const brace-entry-open)
- (const inexpr-class-open) (const inexpr-class-close))
- (choice :tag "Action"
- (set :format "Insert a newline %v"
- :extra-offset 38
- (const :tag "before brace" before)
- (const :tag "after brace" after))
- (function :format "Run function %v" :value c-)
- )))
- :group 'c)
-
-(defcustom c-hanging-colons-alist nil
+ :type
+ `(set ,@(mapcar
+ (lambda (elt)
+ `(cons :format "%v"
+ (c-const-symbol :format "%v: "
+ :size 20
+ :value ,elt)
+ (choice :format "%[Choice%] %v"
+ :value (before after)
+ (set :menu-tag "Before/after"
+ :format "Newline %v brace\n"
+ (const :format "%v, " before)
+ (const :format "%v" after))
+ (function :menu-tag "Function"
+ :format "Run function: %v"
+ :value c-))))
+ '(defun-open defun-close
+ class-open class-close
+ inline-open inline-close
+ block-open block-close
+ substatement-open statement-case-open
+ extern-lang-open extern-lang-close
+ brace-list-open brace-list-close
+ brace-list-intro brace-entry-open
+ namespace-open namespace-close
+ inexpr-class-open inexpr-class-close)))
+ :group 'c)
+
+(defcustom-c-stylevar c-hanging-colons-alist nil
"*Controls the insertion of newlines before and after certain colons.
This variable contains an association list with elements of the
following form: (SYNTACTIC-SYMBOL . ACTION).
See the variable `c-hanging-braces-alist' for the semantics of this
variable. Note however that making ACTION a function symbol is
currently not supported for this variable."
- :type '(repeat
- (cons :format "%v"
- (choice :tag "Syntax"
- (const case-label) (const label) (const access-label)
- (const member-init-intro) (const inher-intro))
- (set :tag "Action"
- :format "%t: %v"
- :extra-offset 8
- (const before) (const after))))
+ :type
+ `(set ,@(mapcar
+ (lambda (elt)
+ `(cons :format "%v"
+ (c-const-symbol :format "%v: "
+ :size 20
+ :value ,elt)
+ (set :format "Newline %v brace\n"
+ (const :format "%v, " before)
+ (const :format "%v" after))))
+ '(case-label label access-label member-init-intro inher-intro)))
:group 'c)
-(defcustom c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
+(defcustom-c-stylevar c-hanging-semi&comma-criteria
+ '(c-semi&comma-inside-parenlist)
"*List of functions that decide whether to insert a newline or not.
The functions in this list are called, in order, whenever the
auto-newline minor mode is activated (as evidenced by a `/a' or `/ah'
:type '(repeat function)
:group 'c)
-(defcustom c-hanging-comment-ender-p t
- "*Controls what \\[fill-paragraph] does to C block comment enders.
-When set to nil, C block comment enders are left on their own line.
-When set to t, block comment enders will be placed at the end of the
-previous line (i.e. they `hang' on that line)."
- :type 'boolean
- :group 'c)
-
-(defcustom c-hanging-comment-starter-p t
- "*Controls what \\[fill-paragraph] does to C block comment starters.
-When set to nil, C block comment starters are left on their own line.
-When set to t, text that follows a block comment starter will be
-placed on the same line as the block comment starter (i.e. the text
-`hangs' on that line)."
- :type 'boolean
- :group 'c)
-
-(defcustom c-backslash-column 48
+(defcustom-c-stylevar c-backslash-column 48
"*Column to insert backslashes when macroizing a region."
:type 'integer
:group 'c)
:type '(set :extra-offset 8 (const alignleft))
:group 'c)
-(defcustom c-label-minimum-indentation 1
+(defcustom-c-stylevar c-label-minimum-indentation 1
"*Minimum indentation for lines inside of top-level constructs.
This variable typically only affects code using the `gnu' style, which
mandates a minimum of one space in front of every line inside
style by default, except `java-mode', which always installs the
\"java\" style (this is for backwards compatibility).
-When the value is an alist, the named style is installed. If the
-major mode is not listed in the alist, then the symbol `other' is
-looked up in the alist, and if found, the associated style is used.
-If `other' is not found in the alist, then \"gnu\" style is used.
-
-Note that if you set any CC Mode variables in the top-level of your
-.emacs file (i.e. *not* in a hook), these get incorporated into the
-`user' style, so you would need to add:
-
- (setq c-default-style '((other . \"user\")))
-
-to see your customizations. This is also true if you use the Custom
-interface -- be sure to set the default style to `user'.
-
-Finally, the default style gets installed before your mode hooks run,
-so you can always override the use of `c-default-style' by making
-calls to `c-set-style' in the appropriate mode hook."
- :type '(choice string
- (repeat :tag "" :menu-tag "Major mode list"
- (cons :tag ""
- (choice :tag "Mode"
- (const c-mode) (const c++-mode) (const objc-mode)
- (const java-mode) (const idl-mode)
- (const pike-mode) (const other))
- (string :tag "Style")
- )))
+When the value is an alist, the major mode symbol is looked up in it
+and the associated style is installed. If the major mode is not
+listed in the alist, then the symbol `other' is looked up in it, and
+if found, the style in that entry is used. If `other' is not found in
+the alist, then \"gnu\" style is used.
+
+The default style gets installed before your mode hooks run, so you
+can always override the use of `c-default-style' by making calls to
+`c-set-style' in the appropriate mode hook.
+
+Tip: If you use different styles in different languages, you probably
+want to set `c-style-variables-are-local-p'."
+ :type '(radio
+ (string :tag "Style in all modes (except Java)")
+ (repeat :tag "Mode-specific styles"
+ :value ((other . "user"))
+ (cons :format "%v"
+ (choice :tag "Mode"
+ (const c-mode) (const c++-mode)
+ (const objc-mode) (const java-mode)
+ (const idl-mode) (const pike-mode)
+ (const other))
+ (string :tag "Style")
+ )))
+ :group 'c)
+
+(put 'c-offsets-alist 'c-stylevar-fallback
+ '((string . c-lineup-dont-change)
+ ;; Relpos: Beg of previous line.
+ (c . c-lineup-C-comments)
+ ;; Relpos: Beg of the comment.
+ (defun-open . 0)
+ ;; Relpos: Boi at the func decl start when inside classes, bol
+ ;; at the func decl start when at top level.
+ (defun-close . 0)
+ ;; Relpos: Boi at the func decl start.
+ (defun-block-intro . +)
+ ;; Relpos: Boi at the block open.
+ (class-open . 0)
+ ;; Relpos: Boi at the class decl start.
+ (class-close . 0)
+ ;; Relpos: Boi at the class decl start.
+ (inline-open . +)
+ ;; Relpos: None for functions (inclass got the relpos then),
+ ;; boi at the lambda start for lambdas.
+ (inline-close . 0)
+ ;; Relpos: For functions: Boi at the func decl start. For
+ ;; lambdas: At the block open if it's at boi, at the boi of the
+ ;; lambda start otherwise.
+ (func-decl-cont . +)
+ ;; Relpos: Boi at the func decl start.
+ (knr-argdecl-intro . +)
+ ;; Relpos: Boi at the current line.
+ (knr-argdecl . 0)
+ ;; Relpos: Boi at the argdecl intro line.
+ (topmost-intro . 0)
+ ;; Relpos: Bol at the last line of previous construct.
+ (topmost-intro-cont . 0)
+ ;; Relpos: Boi at the topmost intro line.
+ (member-init-intro . +)
+ ;; Relpos: Boi at the func decl arglist open.
+ (member-init-cont . 0)
+ ;; Relpos: Beg of the first member init.
+ (inher-intro . +)
+ ;; Relpos: Java: Boi at the class decl start. Otherwise: Boi
+ ;; of current line (a bug?), unless it begins with an inher
+ ;; start colon, in which case boi of previous line is used.
+ (inher-cont . c-lineup-multi-inher)
+ ;; Relpos: Java: At the implements/extends keyword start.
+ ;; Otherwise: At the inher start colon, or boi at the class
+ ;; decl start if the first inherit clause hangs and it's not a
+ ;; func-local inherit clause (when does that occur?).
+ (block-open . 0)
+ ;; Relpos: Inexpr statement: Boi at the the preceding
+ ;; paren. Otherwise: None.
+ (block-close . 0)
+ ;; Relpos: At the open brace if it's at boi. Otherwise boi at
+ ;; the start of the statement the open brace hangs on, or boi
+ ;; at the preceding paren for inexpr statements.
+ (brace-list-open . 0)
+ ;; Relpos: Boi at the brace list decl start, but a starting
+ ;; "typedef" token is ignored.
+ (brace-list-close . 0)
+ ;; Relpos: Boi at the brace list open.
+ (brace-list-intro . +)
+ ;; Relpos: Boi at the brace list open.
+ (brace-list-entry . 0)
+ ;; Relpos: At the first non-ws char after the open paren if the
+ ;; first token is on the same line, otherwise boi at that
+ ;; token.
+ (brace-entry-open . 0)
+ ;; Relpos: Same as brace-list-entry.
+ (statement . 0)
+ ;; Relpos: After a ';' in the condition clause of a for
+ ;; statement: At the first token after the starting paren.
+ ;; Otherwise: Boi at the start of the closest non-hanging
+ ;; previous statement, but after any switch label.
+ (statement-cont . +)
+ ;; Relpos: After the first token in the condition clause of a
+ ;; for statement: At the first token after the starting paren.
+ ;; On the first line in a continued expression that starts with
+ ;; a stream op and there's no stream op on the previous line:
+ ;; Boi of previous line. Otherwise: Boi at the beginning of
+ ;; the statement, but after any type of label.
+ (statement-block-intro . +)
+ ;; Relpos: At the block start if it's at boi, otherwise boi at
+ ;; the start of the statement the open brace hangs on, or boi
+ ;; at the preceding paren for inexpr statements.
+ (statement-case-intro . +)
+ ;; Relpos: At the label keyword (always at boi).
+ (statement-case-open . 0)
+ ;; Relpos: At the label keyword (always at boi).
+ (substatement . +)
+ ;; Relpos: Boi at the containing statement or else clause.
+ (substatement-open . +)
+ ;; Relpos: Boi at the containing statement or else clause.
+ (case-label . 0)
+ ;; Relpos: At the switch block start if it's at boi, otherwise
+ ;; boi at the start of the switch condition clause.
+ (access-label . -)
+ ;; Relpos: Eol (a bug?).
+ (label . 2)
+ ;; Relpos: At the start of the containing block if it's at boi,
+ ;; otherwise boi at the start of the sexp before the block.
+ (do-while-closure . 0)
+ ;; Relpos: Boi at the corresponding while keyword.
+ (else-clause . 0)
+ ;; Relpos: Boi at the corresponding if keyword.
+ (catch-clause . 0)
+ ;; Relpos: Boi at the previous try or catch keyword in the try
+ ;; statement.
+ (comment-intro . c-lineup-comment)
+ ;; Relpos: None.
+ (arglist-intro . +)
+ ;; Relpos: Boi at the open paren.
+ (arglist-cont . 0)
+ ;; Relpos: At the first token after the open paren.
+ (arglist-cont-nonempty . c-lineup-arglist)
+ ;; Relpos: Boi at the open paren.
+ (arglist-close . +)
+ ;; Relpos: Boi at the open paren.
+ (stream-op . c-lineup-streamop)
+ ;; Relpos: Boi at the first stream op in the statement.
+ (inclass . +)
+ ;; Relpos: At the class open brace if it's at boi, otherwise
+ ;; boi at the class decl start.
+ (cpp-macro . -1000)
+ ;; Relpos: Boi.
+ (cpp-macro-cont . c-lineup-dont-change)
+ ;; Relpos: At the macro start (always at boi).
+ (friend . 0)
+ ;; Relpos: None.
+ (objc-method-intro . -1000)
+ ;; Relpos: Boi.
+ (objc-method-args-cont . c-lineup-ObjC-method-args)
+ ;; Relpos: At the method start (always at boi).
+ (objc-method-call-cont . c-lineup-ObjC-method-call)
+ ;; Relpos: At the open bracket.
+ (extern-lang-open . 0)
+ ;; Relpos: Boi at the extern keyword.
+ (extern-lang-close . 0)
+ ;; Relpos: Boi at the corresponding extern keyword.
+ (inextern-lang . +)
+ ;; Relpos: At the extern block open brace if it's at boi,
+ ;; otherwise boi at the extern keyword.
+ (namespace-open . 0)
+ ;; Relpos: Boi at the namespace keyword.
+ (namespace-close . 0)
+ ;; Relpos: Boi at the corresponding namespace keyword.
+ (innamespace . +)
+ ;; Relpos: At the namespace block open brace if it's at boi,
+ ;; otherwise boi at the namespace keyword.
+ (template-args-cont . (c-lineup-template-args +))
+ ;; Relpos: Boi at the decl start.
+ (inlambda . c-lineup-inexpr-block)
+ ;; Relpos: None.
+ (lambda-intro-cont . +)
+ ;; Relpos: Boi at the lambda start.
+ (inexpr-statement . 0)
+ ;; Relpos: None.
+ (inexpr-class . +)
+ ;; Relpos: None.
+ ))
+(defcustom c-offsets-alist nil
+ "Association list of syntactic element symbols and indentation offsets.
+As described below, each cons cell in this list has the form:
+
+ (SYNTACTIC-SYMBOL . OFFSET)
+
+When a line is indented, CC Mode first determines the syntactic
+context of it by generating a list of symbols called syntactic
+elements. This list can contain more than one syntactic element and
+the global variable `c-syntactic-context' contains the context list
+for the line being indented. Each element in this list is actually a
+cons cell of the syntactic symbol and a buffer position. This buffer
+position is called the relative indent point for the line. Some
+syntactic symbols may not have a relative indent point associated with
+them.
+
+After the syntactic context list for a line is generated, CC Mode
+calculates the absolute indentation for the line by looking at each
+syntactic element in the list. It compares the syntactic element
+against the SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it finds a
+match, it adds the OFFSET to the column of the relative indent point.
+The sum of this calculation for each element in the syntactic list is
+the absolute offset for line being indented.
+
+If the syntactic element does not match any in the `c-offsets-alist',
+an error is generated if `c-strict-syntax-p' is non-nil, otherwise the
+element is ignored.
+
+Actually, OFFSET can be an integer, a function, a variable, or one of
+the following symbols: `+', `-', `++', `--', `*', or `/'. These
+latter designate positive or negative multiples of `c-basic-offset',
+respectively: 1, -1, 2, -2, 0.5, and -0.5. If OFFSET is a function,
+it is called with a single argument containing the cons of the
+syntactic element symbol and the relative indent point. The function
+should return an integer offset or nil if it can't decide.
+
+OFFSET can also be a list, in which case it is recursively evaluated
+using the semantics described above. The first element of the list to
+return a non-nil value succeeds. If none of the elements returns a
+non-nil value, then what happends depends on the value of
+`c-strict-syntax-p'. When `c-strict-syntax-p' is nil, then an offset
+of zero is used, otherwise an error is generated.
+
+`c-offsets-alist' is a style variable. This means that the offsets on
+this variable are normally taken from the style system in CC Mode
+\(see `c-default-style' and `c-styles-alist'). However, any offsets
+put explicitly on this list will override the style system when a CC
+Mode buffer is initialized \(there is a variable
+`c-old-style-variable-behavior' that changes this, though).
+
+Here is the current list of valid syntactic element symbols:
+
+ string -- Inside multi-line string.
+ c -- Inside a multi-line C style block comment.
+ defun-open -- Brace that opens a function definition.
+ defun-close -- Brace that closes a function definition.
+ defun-block-intro -- The first line in a top-level defun.
+ class-open -- Brace that opens a class definition.
+ class-close -- Brace that closes a class definition.
+ inline-open -- Brace that opens an in-class inline method.
+ inline-close -- Brace that closes an in-class inline method.
+ func-decl-cont -- The region between a function definition's
+ argument list and the function opening brace
+ (excluding K&R argument declarations). In C, you
+ cannot put anything but whitespace and comments
+ between them; in C++ and Java, throws declarations
+ and other things can appear in this context.
+ knr-argdecl-intro -- First line of a K&R C argument declaration.
+ knr-argdecl -- Subsequent lines in a K&R C argument declaration.
+ topmost-intro -- The first line in a topmost construct definition.
+ topmost-intro-cont -- Topmost definition continuation lines.
+ member-init-intro -- First line in a member initialization list.
+ member-init-cont -- Subsequent member initialization list lines.
+ inher-intro -- First line of a multiple inheritance list.
+ inher-cont -- Subsequent multiple inheritance lines.
+ block-open -- Statement block open brace.
+ block-close -- Statement block close brace.
+ brace-list-open -- Open brace of an enum or static array list.
+ brace-list-close -- Close brace of an enum or static array list.
+ brace-list-intro -- First line in an enum or static array list.
+ brace-list-entry -- Subsequent lines in an enum or static array list.
+ brace-entry-open -- Subsequent lines in an enum or static array
+ list that start with an open brace.
+ statement -- A C (or like) statement.
+ statement-cont -- A continuation of a C (or like) statement.
+ statement-block-intro -- The first line in a new statement block.
+ statement-case-intro -- The first line in a case \"block\".
+ statement-case-open -- The first line in a case block starting with brace.
+ substatement -- The first line after an if/while/for/do/else.
+ substatement-open -- The brace that opens a substatement block.
+ case-label -- A `case' or `default' label.
+ access-label -- C++ private/protected/public access label.
+ label -- Any ordinary label.
+ do-while-closure -- The `while' that ends a do/while construct.
+ else-clause -- The `else' of an if/else construct.
+ catch-clause -- The `catch' or `finally' of a try/catch construct.
+ comment-intro -- A line containing only a comment introduction.
+ arglist-intro -- The first line in an argument list.
+ arglist-cont -- Subsequent argument list lines when no
+ arguments follow on the same line as the
+ arglist opening paren.
+ arglist-cont-nonempty -- Subsequent argument list lines when at
+ least one argument follows on the same
+ line as the arglist opening paren.
+ arglist-close -- The solo close paren of an argument list.
+ stream-op -- Lines continuing a stream operator construct.
+ inclass -- The construct is nested inside a class definition.
+ Used together with e.g. `topmost-intro'.
+ cpp-macro -- The start of a C preprocessor macro definition.
+ cpp-macro-cont -- Subsequent lines in a multi-line C preprocessor
+ macro definition.
+ friend -- A C++ friend declaration.
+ objc-method-intro -- The first line of an Objective-C method definition.
+ objc-method-args-cont -- Lines continuing an Objective-C method definition.
+ objc-method-call-cont -- Lines continuing an Objective-C method call.
+ extern-lang-open -- Brace that opens an external language block.
+ extern-lang-close -- Brace that closes an external language block.
+ inextern-lang -- Analogous to the `inclass' syntactic symbol,
+ but used inside extern constructs.
+ namespace-open -- Brace that opens a C++ namespace block.
+ namespace-close -- Brace that closes a C++ namespace block.
+ innamespace -- Analogous to the `inextern-lang' syntactic
+ symbol, but used inside C++ namespace constructs.
+ template-args-cont -- C++ template argument list continuations.
+ inlambda -- In the header or body of a lambda function.
+ lambda-intro-cont -- Continuation of the header of a lambda function.
+ inexpr-statement -- The statement is inside an expression.
+ inexpr-class -- The class is inside an expression. Used e.g. for
+ Java anonymous classes."
+ :type
+ `(set :format "%{%t%}:
+ Override style setting
+ | Syntax Offset
+%v"
+ ,@(mapcar
+ (lambda (elt)
+ `(cons :format "%v"
+ :value ,elt
+ (c-const-symbol :format "%v: "
+ :size 25)
+ (sexp :format "%v"
+ :validate
+ (lambda (widget)
+ (unless (c-valid-offset (widget-value widget))
+ (widget-put widget :error "Invalid offset")
+ widget)))))
+ (get 'c-offsets-alist 'c-stylevar-fallback)))
:group 'c)
(defcustom c-style-variables-are-local-p nil
The list of variables to buffer localize are:
c-offsets-alist
c-basic-offset
- c-file-style
- c-file-offsets
c-comment-only-line-offset
+ c-block-comment-prefix
+ c-comment-prefix-regexp
c-cleanup-list
c-hanging-braces-alist
c-hanging-colons-alist
- c-hanging-comment-starter-p
- c-hanging-comment-ender-p
+ c-hanging-semi&comma-criteria
c-backslash-column
c-label-minimum-indentation
c-special-indent-hook
(defcustom c-mode-hook nil
"*Hook called by `c-mode'."
- :type '(hook :format "%{C Mode Hook%}:\n%v")
+ :type 'hook
:group 'c)
(defcustom c++-mode-hook nil
:type 'hook
:group 'c)
+(defcustom pike-mode-hook nil
+ "*Hook called by `pike-mode'."
+ :type 'hook
+ :group 'c)
+
(defcustom c-mode-common-hook nil
"*Hook called by all CC Mode modes for common initializations."
:type '(hook :format "%{CC Mode Common Hook%}:\n%v")
braces in column zero, this can degrade performance about as much.
This variable only has effect in XEmacs.")
+(defcustom c-old-style-variable-behavior nil
+ "*Enables the old style variable behavior when non-nil.
+
+Normally the values of the style variables will override the style
+settings specified by the variables `c-default-style' and
+`c-styles-alist'. However, in CC Mode 5.25 and earlier, it was the
+other way around, meaning that changes made to the style variables
+from e.g. Customize would not take effect unless special precautions
+were taken. That was confusing, especially for novice users.
+
+It's believed that despite this change, the new behavior will still
+produce the same results for most old CC Mode configurations, since
+all style variables are per default set in a special non-override
+state. Set this variable only if your configuration has stopped
+working due to this change.")
+
+
\f
;; Non-customizable variables, still part of the interface to CC Mode
(defvar c-file-style nil
Note that file style settings are applied before file offset settings
as designated in the variable `c-file-offsets'.")
+(make-variable-buffer-local 'c-file-style)
(defvar c-file-offsets nil
"Variable interface for setting offsets via File Local Variables.
Note that file offset settings are applied after file style settings
as designated in the variable `c-file-style'.")
+(make-variable-buffer-local 'c-file-offsets)
(defvar c-syntactic-context nil
"Variable containing syntactic analysis list during indentation.")
-(defvar c-indentation-style c-default-style
- "Name of style installed in the current buffer.")
+(defvar c-indentation-style nil
+ "Name of the currently installed style.")
\f
features supporting those needed by CC Mode. Here's the current
supported list, along with the values for this variable:
- XEmacs 19: (8-bit)
- XEmacs 20: (8-bit)
- Emacs 19: (1-bit)
+ XEmacs 19, 20, 21: (8-bit)
+ Emacs 19, 20: (1-bit)
Infodock (based on XEmacs) has an additional symbol on this list:
`infodock'.")