summaryrefslogtreecommitdiff
path: root/lisp/progmodes
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/cc-align.el437
-rw-r--r--lisp/progmodes/cc-cmds.el1526
-rw-r--r--lisp/progmodes/cc-compat.el16
-rw-r--r--lisp/progmodes/cc-defs.el265
-rw-r--r--lisp/progmodes/cc-engine.el303
-rw-r--r--lisp/progmodes/cc-langs.el208
-rw-r--r--lisp/progmodes/cc-menus.el77
-rw-r--r--lisp/progmodes/cc-mode.el180
-rw-r--r--lisp/progmodes/cc-styles.el445
-rw-r--r--lisp/progmodes/cc-vars.el747
10 files changed, 2778 insertions, 1426 deletions
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index c051172ce96..9244d6e4714 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -1,8 +1,8 @@
;;; 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
@@ -29,16 +29,22 @@
;; 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)
;; 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
@@ -65,7 +71,7 @@
(- (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)
@@ -78,7 +84,11 @@
))))
(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
@@ -89,7 +99,12 @@
(- 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
@@ -99,15 +114,16 @@
(- 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)
@@ -124,10 +140,12 @@
(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)
@@ -135,7 +153,9 @@
(- (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))
@@ -149,110 +169,215 @@
)))
(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)
@@ -264,18 +389,33 @@
))))
(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))
@@ -307,13 +447,29 @@
(- (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)
@@ -336,8 +492,11 @@
(- 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)))
@@ -357,8 +516,11 @@
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)))
@@ -377,31 +539,57 @@
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))))
(defun c-snug-do-while (syntax pos)
@@ -450,6 +638,7 @@ indentation amount."
;; 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
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 9877832804a..05d2599d957 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1,8 +1,8 @@
;;; 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
@@ -28,11 +28,17 @@
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; 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 'cc-engine)
+
(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
@@ -331,7 +337,7 @@ This function does various newline cleanups based on the value of
;; 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)
@@ -345,19 +351,36 @@ This function does various newline cleanups based on the value of
;; 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?
@@ -598,8 +621,8 @@ or \"/ah\" string on the mode line, some newline cleanups are done if
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))
@@ -647,7 +670,8 @@ the colon is inserted inside a literal."
(insert "} catch (")))
(goto-char (- (point-max) pos))
))
- (funcall old-blink-paren)))))
+ (if old-blink-paren
+ (funcall old-blink-paren))))))
@@ -692,6 +716,7 @@ Unlike the built-in `beginning-of-defun' this tries to be smarter
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)
@@ -706,13 +731,16 @@ defun."
(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'."
@@ -722,16 +750,25 @@ 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)))
(defun c-beginning-of-statement (&optional count lim sentence-flag)
@@ -759,18 +796,12 @@ comment."
(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))))
@@ -780,23 +811,72 @@ comment."
(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)
@@ -810,89 +890,143 @@ comment."
(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
@@ -987,8 +1121,10 @@ comment."
(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))
@@ -996,11 +1132,12 @@ comment."
(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
@@ -1015,93 +1152,89 @@ comment."
)))))
-;; 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)))
(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)
@@ -1112,36 +1245,50 @@ move backward across a preprocessor conditional."
;; 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)))
@@ -1217,8 +1364,9 @@ of the expression is preserved.
"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
@@ -1259,7 +1407,8 @@ Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
(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."
@@ -1342,13 +1491,16 @@ Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
(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
@@ -1560,12 +1712,288 @@ command to conveniently insert and align the necessary backslashes."
(delete-region (1+ (point))
(progn (skip-chars-backward " \t") (point)))))))
+
+;;; 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
@@ -1580,274 +2008,376 @@ If point is in any other situation, i.e. in normal code, do nothing.
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))))
(provide 'cc-cmds)
diff --git a/lisp/progmodes/cc-compat.el b/lisp/progmodes/cc-compat.el
index d7556a6084e..93b4e5bc5af 100644
--- a/lisp/progmodes/cc-compat.el
+++ b/lisp/progmodes/cc-compat.el
@@ -1,9 +1,9 @@
;;; 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
@@ -40,9 +40,15 @@
;;; 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)
;; In case c-mode.el isn't loaded
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 2ae6c7bdcf0..e9b1a30d32e 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -1,8 +1,8 @@
;;; 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
@@ -28,10 +28,8 @@
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-
;; 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
@@ -48,7 +46,7 @@
(require 'cc-mode-19))
-(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:
;;
@@ -63,76 +61,105 @@
;; 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)))
(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
@@ -152,17 +179,78 @@
(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
@@ -188,13 +276,14 @@
(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.
@@ -209,6 +298,7 @@
(cond
;; XEmacs
((and (fboundp 'region-active-p)
+ (boundp 'zmacs-regions)
zmacs-regions)
(region-active-p))
;; Emacs
@@ -219,6 +309,17 @@
(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)
+
(provide 'cc-defs)
;;; cc-defs.el ends here
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index fccb032e62c..08ed5eb2664 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -1,8 +1,8 @@
;;; 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
@@ -28,10 +28,17 @@
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; 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 'cc-langs)
+
;; 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
@@ -98,7 +105,7 @@
;; 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)
@@ -112,6 +119,7 @@
(<= lim (point))
(not (c-in-literal lim))
(not (eq (char-before) ?_))
+ c-conditional-key
(looking-at c-conditional-key)
))))
;; did we find a conditional?
@@ -144,8 +152,10 @@
(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
@@ -170,7 +180,7 @@
;; `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)
@@ -187,7 +197,7 @@
;; 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 ()
@@ -254,7 +264,7 @@
(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)))
@@ -264,28 +274,13 @@
)
(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)))))
@@ -428,16 +423,18 @@
(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)))
@@ -460,18 +457,20 @@
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.
@@ -481,7 +480,7 @@
(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")
@@ -495,32 +494,65 @@
;; 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++
@@ -536,18 +568,16 @@
(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))))
@@ -558,11 +588,11 @@
;; 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))
@@ -1230,28 +1260,32 @@ brace."
;; 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
@@ -1323,19 +1357,6 @@ brace."
;; 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)))))
-
;; This function implements the main decision tree for determining the
;; syntactic analysis of the current line of code. Yes, it's huge and
@@ -1425,10 +1446,7 @@ brace."
(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))
@@ -1638,9 +1656,16 @@ brace."
;; 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))
@@ -1659,7 +1684,6 @@ brace."
;; 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)
@@ -1667,15 +1691,16 @@ brace."
(= (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)
@@ -1708,7 +1733,7 @@ brace."
;; 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)
@@ -1821,7 +1846,13 @@ brace."
(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)
@@ -1839,12 +1870,9 @@ brace."
;; 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)))
@@ -1859,7 +1887,10 @@ brace."
(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)))
@@ -1961,10 +1992,13 @@ brace."
((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.
@@ -2034,7 +2068,7 @@ brace."
(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)
@@ -2078,7 +2112,14 @@ brace."
(= (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?
@@ -2131,7 +2172,8 @@ brace."
(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.
@@ -2405,6 +2447,17 @@ With universal argument, inserts the analysis as a comment on that line."
))
(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)))))
+
(provide 'cc-engine)
;;; cc-engine.el ends here
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 912e36446bb..255ce7420e2 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -1,8 +1,8 @@
;;; 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
@@ -28,11 +28,38 @@
;; 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)
-(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)
+
;; Regular expressions and other values which must be parameterized on
;; a per-language basis.
@@ -56,7 +83,7 @@
;; 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\\)")
@@ -86,11 +113,18 @@
(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)
+
;; 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)
@@ -99,6 +133,8 @@
;; 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)
@@ -109,6 +145,8 @@
(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)))
@@ -132,6 +170,10 @@
;; 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 "/\\(/\\|[*][*]?\\)")
@@ -173,7 +215,7 @@
;; 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)
@@ -225,47 +267,86 @@
;; 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))
@@ -280,14 +361,6 @@
(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")))
)
@@ -386,31 +459,49 @@ Note that the style variables are always made local to the buffer."
;; 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)
@@ -430,10 +521,6 @@ Note that the style variables are always made local to the buffer."
;;(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)
@@ -524,6 +611,17 @@ Note that the style variables are always made local to the buffer."
;;(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++"))
diff --git a/lisp/progmodes/cc-menus.el b/lisp/progmodes/cc-menus.el
index 83dd49f21c3..8eb10050d01 100644
--- a/lisp/progmodes/cc-menus.el
+++ b/lisp/progmodes/cc-menus.el
@@ -1,8 +1,8 @@
;;; 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
@@ -28,8 +28,23 @@
;; 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)))
@@ -52,14 +67,12 @@ For example:
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')
@@ -77,37 +90,35 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
; 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
@@ -115,10 +126,10 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
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]+"
@@ -126,8 +137,8 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
"[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
@@ -135,22 +146,20 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
"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*
@@ -398,6 +407,10 @@ Example:
; ())
; FIXME: Please contribute one!
+(defun cc-imenu-init (mode-generic-expression)
+ (setq imenu-generic-expression mode-generic-expression
+ imenu-case-fold-search nil))
+
(provide 'cc-menus)
;;; cc-menus.el ends here
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 06e7a18b0d5..83c8c566104 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1,8 +1,8 @@
;;; 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
@@ -10,7 +10,7 @@
;; 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!
@@ -85,27 +85,34 @@
;;; Code:
-
-(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)
-
;; Other modes and packages which depend on CC Mode should do the
;; following to make sure everything is loaded and available for their
@@ -120,15 +127,17 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
(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)))
))
@@ -162,10 +171,10 @@ Key bindings:
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))
@@ -205,9 +214,9 @@ Key bindings:
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))
@@ -241,15 +250,14 @@ Key bindings:
(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))
@@ -285,6 +293,10 @@ Key bindings:
(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
@@ -294,9 +306,8 @@ Key bindings:
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))
@@ -330,15 +341,16 @@ Key bindings:
(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))
@@ -373,6 +385,7 @@ Key bindings:
(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
@@ -381,14 +394,45 @@ Key bindings:
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))
+(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))))
+
+
;; bug reporting
(defconst c-mode-help-address
@@ -423,36 +467,40 @@ Key bindings:
((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
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index f394a9b3fdc..7cfb1d1e99f 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -1,8 +1,8 @@
;;; 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
@@ -28,10 +28,16 @@
;; 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)
+
;; Warning: don't eval-defun this constant or you'll break style inheritance.
@@ -50,8 +56,7 @@
(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)
@@ -71,6 +76,8 @@
(substatement-open . 0)
(label . 0)
(statement-cont . +)
+ (inline-open . 0)
+ (inexpr-class . 0)
))
)
("stroustrup"
@@ -85,13 +92,32 @@
("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)
@@ -124,7 +150,7 @@
)
("python"
(indent-tabs-mode . t)
- (fill-column . 72)
+ (fill-column . 78)
(c-basic-offset . 8)
(c-offsets-alist . ((substatement-open . 0)
(inextern-lang . 0)
@@ -138,21 +164,18 @@
(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)
@@ -161,7 +184,6 @@
(inher-cont . c-lineup-java-inher)
(func-decl-cont . c-lineup-java-throws)
))
-
)
)
"Styles of indentation.
@@ -175,7 +197,7 @@ for that variable when using the selected style.
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
@@ -197,9 +219,10 @@ to add new styles or modify existing styles (it is not a good idea to
modify existing styles -- you should create a new style that inherits
the existing style.")
+
;; 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)))
@@ -211,50 +234,68 @@ the existing style.")
(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)))
@@ -262,7 +303,12 @@ style 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))
@@ -292,195 +338,6 @@ STYLE using `c-set-style' if the optional SET-P flag is non-nil."
-(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 -
@@ -529,16 +386,21 @@ Here is the current list of valid syntactic element symbols:
(goto-char relpos)
(current-column))
0)
- (c-evaluate-offset offset langelem symbol))
+ (or (and (numberp offset) offset)
+ (and (symbolp offset) (symbol-value offset))
+ 0))
))
+
(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, "
@@ -574,11 +436,11 @@ Here is the current list of valid syntactic element symbols:
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
@@ -588,7 +450,7 @@ offset for that syntactic element. Optional ADD says to add SYMBOL to
(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
@@ -601,33 +463,19 @@ offset for that syntactic element. Optional ADD says to add SYMBOL to
(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))
-
-(defun c-copy-tree (tree)
- (if (consp tree)
- (cons (c-copy-tree (car tree))
- (c-copy-tree (cdr tree)))
- tree))
+
(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
@@ -639,39 +487,42 @@ offset for that syntactic element. Optional ADD says to add SYMBOL to
(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.
@@ -685,24 +536,14 @@ instead of `make-variable-buffer-local'."
(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))
))
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index fd05cbdda10..25608653c9e 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1,8 +1,8 @@
;;; 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
@@ -29,17 +29,124 @@
;; 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)
+
+
+;;; 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))))
+
+
+;;; 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)
@@ -48,20 +155,11 @@ and the syntactic symbol is ignored."
: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,
@@ -72,7 +170,7 @@ literals -- defined as comments and strings -- and inside preprocessor
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.
@@ -93,7 +191,7 @@ should be inserted. Value must be a function taking no arguments."
: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:
@@ -102,8 +200,12 @@ 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
@@ -112,25 +214,77 @@ Just an integer as value is equivalent to (<val> . -1000)."
: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
@@ -140,12 +294,11 @@ mode name. Valid symbols are:
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
@@ -171,21 +324,22 @@ mode name. Valid symbols are:
(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
@@ -197,12 +351,12 @@ SYNTACTIC-SYMBOL can be any of: 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, 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,
@@ -214,28 +368,35 @@ at which the brace was inserted. The function must return a list as
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).
@@ -246,18 +407,21 @@ member-init-intro, or inher-intro.
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'
@@ -274,24 +438,7 @@ then no newline is inserted."
: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)
@@ -318,7 +465,7 @@ Only currently supported behavior is `alignleft'."
: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
@@ -347,32 +494,336 @@ When the value is a string, all CC Mode major modes will install this
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
@@ -385,14 +836,13 @@ localized, they cannot be made global again.
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
@@ -402,7 +852,7 @@ The list of variables to buffer localize are:
(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
@@ -425,6 +875,11 @@ The list of variables to buffer localize are:
: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")
@@ -446,6 +901,23 @@ styles that conform to the Emacs recommendation of putting these
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.")
+
+
;; Non-customizable variables, still part of the interface to CC Mode
(defvar c-file-style nil
@@ -456,6 +928,7 @@ will set the style of the file to this value automatically.
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.
@@ -466,12 +939,13 @@ automatically.
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.")
@@ -511,9 +985,8 @@ There are many flavors of Emacs out there, each with different
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'.")