Since there’s a lot of normal text in comments and string literals, CC Mode provides features to edit these like in text mode. It does this by hooking in on the different line breaking functions and tuning relevant variables as necessary.
To make Emacs recognize comments and treat text in them as normal paragraphs, CC Mode makes several standard variables24 buffer-local and modifies them according to the language syntax and the comment line prefix.
This style variable contains the regexp used to recognize the comment line prefix, which is the line decoration that starts every line in a comment. The variable is either the comment line prefix itself, or (more usually) an association list with different values for different languages. The symbol for the major mode is looked up in the alist to get the regexp for the language, and if it isn’t found then the special symbol ‘other’ is looked up instead.
When a comment line gets divided by M-j or the like, CC Mode inserts the comment line prefix from a neighboring line at the start of the new line. The default value of c-comment-prefix-regexp is ‘//+\\|\\**’, which matches C++ style line comments like
// blah blah
with two or more slashes in front of them, and the second and subsequent lines of C style block comments like
/* * blah blah */
with zero or more stars at the beginning of every line. If you change
this variable, please make sure it still matches the comment starter
(i.e. //
) of line comments and the line prefix inside
block comments.
Also note that since CC Mode uses the value of
c-comment-prefix-regexp
to set up several other variables at
mode initialization, there won’t be any effect if you just change it
inside a CC Mode buffer. You need to call the command
c-setup-paragraph-variables
too, to update those other
variables. That’s also the case if you modify
c-comment-prefix-regexp
in a mode hook, since CC Mode will
already have set up these variables before calling the hook.
In comments, CC Mode uses c-comment-prefix-regexp
to adapt
the line prefix from the other lines in the comment.
CC Mode uses adaptive fill mode (see Adaptive Fill in GNU Emacs Manual) to make Emacs correctly keep the line prefix when filling paragraphs. That also makes Emacs preserve the text indentation inside the comment line prefix. E.g. in the following comment, both paragraphs will be filled with the left margins of the texts kept intact:
/* Make a balanced b-tree of the nodes in the incoming * stream. But, to quote the famous words of Donald E. * Knuth, * * Beware of bugs in the above code; I have only * proved it correct, not tried it. */
It’s also possible to use other adaptive filling packages, notably Kyle
E. Jones’ Filladapt package25,
which handles things like bulleted lists nicely. There’s a convenience
function c-setup-filladapt
that tunes the relevant variables in
Filladapt for use in CC Mode. Call it from a mode hook, e.g. with
something like this in your .emacs:
(defun my-c-mode-common-hook () (c-setup-filladapt) (filladapt-mode 1)) (add-hook 'c-mode-common-hook 'my-c-mode-common-hook)
Normally the comment line prefix inserted for a new line inside a comment is deduced from other lines in it. However there’s one situation when there’s no hint about what the prefix should look like, namely when a block comment is broken for the first time. This style variable26 is used then as the comment prefix. It defaults to ‘* ’27, which makes a comment
/* Got O(n^2) here, which is a Bad Thing. */
break into
/* Got O(n^2) here, which * is a Bad Thing. */
Note that it won’t work to adjust the indentation by putting leading
spaces in c-block-comment-prefix
, since CC Mode still uses the
normal indentation engine to indent the line. Thus, the right way to
fix the indentation is by customizing the c
syntactic symbol. It
defaults to c-lineup-C-comments
, which handles the indentation of
most common comment styles, see Line-Up Functions.
When auto fill mode is enabled, CC Mode can selectively ignore it depending on the context the line break would occur in, e.g. to never break a line automatically inside a string literal. This variable takes a list of symbols for the different contexts where auto-filling never should occur:
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.
By default, c-ignore-auto-fill
is set to (string cpp
code)
, which means that when auto-fill mode is activated,
auto-filling only occurs in comments. In literals, it’s often
desirable to have explicit control over newlines. In preprocessor
directives, the necessary ‘\’ escape character before the newline
is not automatically inserted, so an automatic line break would
produce invalid code. In normal code, line breaks are normally
dictated by some logical structure in the code rather than the last
whitespace character, so automatic line breaks there will produce poor
results in the current implementation.
If inside a comment and comment-multi-line
(see Auto Fill in GNU Emacs Manual is non-nil
, the indentation and
line prefix are preserved. 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.
Note that CC Mode sets comment-multi-line
to t
at
startup. The reason is that M-j could otherwise produce sequences
of single line block comments for texts that should logically be treated
as one comment, and the rest of the paragraph handling code
(e.g. M-q and M-a) can’t cope with that, which would lead to
inconsistent behavior.
comment-start
, comment-end
,
comment-start-skip
, paragraph-start
,
paragraph-separate
, paragraph-ignore-fill-prefix
,
adaptive-fill-mode
, adaptive-fill-regexp
, and
adaptive-fill-first-line-regexp
.
It’s available from
http://www.wonderworks.com/. As of version 2.12, it does however
lack a feature that makes it work suboptimally when
c-comment-prefix-regexp
matches the empty string (which it does
by default). A patch for that is available from
the CC Mode web site.
In versions before 5.26, this variable was called
c-comment-continuation-stars
. As a compatibility measure,
CC Mode still uses the value on that variable if it’s set.
Actually, this default setting of
c-block-comment-prefix
typically gets overridden by the default
style gnu
, which sets it to blank. You can see the line
splitting effect described here by setting a different style,
e.g. k&r
See Choosing a Style.