ccmode: Custom Filling and Breaking
7 Customizing Filling and Line Breaking
***************************************
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 variables(1) buffer-local and
modifies them according to the language syntax and the comment line
prefix.
-- User Option: c-comment-prefix-regexp
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 ((emacs)Adaptive Fill) 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 package(2), 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)
-- User Option: c-block-comment-prefix
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 variable(3) is used then as the comment prefix. It
defaults to ‘* ’(4), 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.
-- User Option: c-ignore-auto-fill
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’ ((emacs)Auto
Fill 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.
---------- Footnotes ----------
(1) ‘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’.
(2) 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.
(3) 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.
(4) 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’ Choosing a Style.