# HG changeset patch # User Gerd Moellmann # Date 945023059 0 # Node ID 03befb219d03ab79edebe1141008052a03f7a780 # Parent e719053e967a3492c20fd57522f056df2262891c Installed version 5.26 diff -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-align.el --- a/lisp/progmodes/cc-align.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-align.el Sun Dec 12 18:24:19 1999 +0000 @@ -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-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 ((eol (c-point 'eol))) + (back-to-indentation) + (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 + "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)) - (stars (progn (back-to-indentation) - (skip-chars-forward "*"))) - (langelem-col (c-langelem-col langelem))) - (back-to-indentation) - (if (not (re-search-forward "/\\([*]+\\)" (c-point 'eol) t)) - (progn - (if (not (looking-at "[*]+")) + (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-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) + (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 + "Do not change the indentation of the current line. + +Works with: Any syntactic symbol." (save-excursion (back-to-indentation) - (current-column))) - + (- (current-column) (c-langelem-col langelem)))) (defun c-snug-do-while (syntax pos) @@ -450,6 +638,7 @@ ;; 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 -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-cmds.el --- a/lisp/progmodes/cc-cmds.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-cmds.el Sun Dec 12 18:24:19 1999 +0000 @@ -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 + (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) -(eval-when-compile - (require 'cc-defs)) - (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 @@ ;; 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 @@ ;; 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 @@ 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 @@ (insert "} catch ("))) (goto-char (- (point-max) pos)) )) - (funcall old-blink-paren))))) + (if old-blink-paren + (funcall old-blink-paren)))))) @@ -692,6 +716,7 @@ 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 @@ (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 @@ (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 @@ (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 @@ (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 @@ (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) ?{) - (if (or (= here last) - (save-excursion - (and (c-safe (progn (up-list -1) t)) - (/= (char-after) ?{)))) - (progn (forward-char) - (throw 'done nil)) - (goto-char last) - (throw 'done t))) - ((and (= (char-after) ?}) - (/= here last)) + (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)) - ((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))) + ((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) + (memq (char-after last) '(?\) ?}))) + (if (and (eq (char-before) ?}) + (eq (char-after) ?\;)) + (backward-char)) + (goto-char last) + (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 @@ (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 @@ (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 @@ ))))) -;; 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) t) + (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-backward-conditional (count &optional up-flag) +(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 1) + (c-keep-region-active)) + +(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 @@ ;; 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 @@ "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 @@ (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 @@ (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 @@ (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 @@ 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 + ;; 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 - (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))) + (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) + (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) - ;; 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. +(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))) - ;; 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))))))))) +(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. - ;; 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))) - (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))) - (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 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 -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-compat.el --- a/lisp/progmodes/cc-compat.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-compat.el Sun Dec 12 18:24:19 1999 +0000 @@ -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 -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-defs.el --- a/lisp/progmodes/cc-defs.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-defs.el Sun Dec 12 18:24:19 1999 +0000 @@ -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 -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-engine.el --- a/lisp/progmodes/cc-engine.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-engine.el Sun Dec 12 18:24:19 1999 +0000 @@ -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 + (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) + -(eval-when-compile - (require 'cc-defs)) - ;; 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 @@ ;; 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 @@ ;; 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 @@ (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 @@ ;; 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 @@ ;; 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 @@ (= (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 @@ ;; 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 @@ (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 @@ ;; 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 @@ (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 @@ ((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 @@ (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 @@ (= (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 @@ (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 @@ )) (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 -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-langs.el --- a/lisp/progmodes/cc-langs.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-langs.el Sun Dec 12 18:24:19 1999 +0000 @@ -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 '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 'adaptive-fill-mode) (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 @@ ;; 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 @@ ;;(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 @@ ;;(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 -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-menus.el --- a/lisp/progmodes/cc-menus.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-menus.el Sun Dec 12 18:24:19 1999 +0000 @@ -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 @@ 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 @@ ; 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 @@ 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-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 @@ "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 @@ ; ()) ; 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 -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-mode.el --- a/lisp/progmodes/cc-mode.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-mode.el Sun Dec 12 18:24:19 1999 +0000 @@ -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-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))) -(eval-and-compile - (require 'cc-defs)) +(require 'cc-defs) ; Not meaningless; this passes on require's from cc-defs. (require 'cc-menus) (require 'cc-vars) +(require 'cc-styles) +(require 'cc-langs) (require 'cc-engine) -(require 'cc-langs) (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 @@ (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 @@ 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 @@ 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 @@ (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 @@ (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 @@ 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 @@ (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 @@ (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 @@ 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 @@ ((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 -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-styles.el --- a/lisp/progmodes/cc-styles.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-styles.el Sun Dec 12 18:24:19 1999 +0000 @@ -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. +(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-vars) -;; explicit compile-time dependencies -(eval-when-compile - (require 'cc-defs)) ;; 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 @@ 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 @@ 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 @@ (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 @@ (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 @@ -(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 @@ (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 @@ 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 @@ (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 (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 @@ (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 @@ (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 -r e719053e967a -r 03befb219d03 lisp/progmodes/cc-vars.el --- a/lisp/progmodes/cc-vars.el Sun Dec 12 16:13:50 1999 +0000 +++ b/lisp/progmodes/cc-vars.el Sun Dec 12 18:24:19 1999 +0000 @@ -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,29 +29,18 @@ ;; 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) -(require 'custom) -(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." - :type 'boolean - :group 'c) - -(defcustom c-echo-syntactic-information-p nil - "*If non-nil, syntactic info is echoed when the line is indented." - :type 'boolean - :group 'c) - -(defcustom c-basic-offset 4 - "*Amount of basic offset used by + and - symbols in `c-offsets-alist'." - :type 'integer - :group 'c) +;;; Helpers ;; This widget will show up in newer versions of the Custom library (or (get 'other 'widget-type) @@ -62,6 +51,115 @@ :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. + +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) + +(defcustom c-echo-syntactic-information-p nil + "*If non-nil, syntactic info is echoed when the line is indented." + :type 'boolean + :group 'c) + +(defcustom-c-stylevar c-basic-offset 4 + "*Amount of basic offset used by + and - symbols in `c-offsets-alist'." + :type 'integer + :group 'c) + (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 @@ 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 @@ :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 @@ 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 ( . -1000)." - :type '(choice (integer :tag "Non-anchored offset") +Just an integer as value is equivalent to ( . -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 @@ :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) -(defcustom c-cleanup-list '(scope-operator) +(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-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 @@ 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 @@ (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 @@ 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 @@ 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) + :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-hanging-colons-alist nil +(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 @@ 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 @@ :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 @@ :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 @@ 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. +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. -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\"))) +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) -to see your customizations. This is also true if you use the Custom -interface -- be sure to set the default style to `user'. +(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: -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") - ))) + (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 @@ 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 @@ (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 @@ :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 @@ 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 @@ 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 @@ 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 @@ 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'.")