The c-offsets-alist
variable is where you customize all your
indentations. You simply need to decide what additional offset you want
to add for every syntactic symbol. You can use the command C-c
C-o (c-set-offset
) as the way to set offsets, both interactively
and from your mode hook. Also, you can set up styles of
indentation just like in BOCM. Most likely, you'll
find one of the pre-defined styles will suit your needs, but if not,
this section will describe how to set up basic editing configurations.
See section Styles for an explanation of how to set up named styles.
As mentioned previously, the variable c-offsets-alist
is an
association list between syntactic symbols and the offsets to be applied
for those symbols. In fact, these offset values can be an integer, a
function or variable name, or one of the following symbols: +
,
-
, ++
, --
, *
, or /
. These symbols
describe offset in multiples of the value of the variable
c-basic-offset
. By defining a style's indentation in terms of
this fundamental variable, you can change the amount of whitespace given
to an indentation level while leaving the same relationship between
levels. Here are multiples of c-basic-offset
that the special
symbols correspond to:
+
= c-basic-offset
times 1
-
= c-basic-offset
times -1
++
= c-basic-offset
times 2
--
= c-basic-offset
times -2
*
= c-basic-offset
times 0.5
/
= c-basic-offset
times -0.5
So, for example, because most of the default offsets are defined in
terms of +
, -
, and 0
, if you like the general
indentation style, but you use 4 spaces instead of 2 spaces per level,
you can probably achieve your style just by changing
c-basic-offset
like so (in your `.emacs' file)(9):
(setq-default c-basic-offset 4)
This would change
int add( int val, int incr, int doit ) { if( doit ) { return( val + incr ); } return( val ); }
to
int add( int val, int incr, int doit ) { if( doit ) { return( val + incr ); } return( val ); }
To change indentation styles more radically, you will want to change the
value associated with the syntactic symbols in the
c-offsets-alist
variable. First, I'll show you how to do that
interactively, then I'll describe how to make changes to your
`.emacs' file so that your changes are more permanent.
As an example of how to customize indentation, let's change the style of example 2 above from:
1: int add( int val, int incr, int doit ) 2: { 3: if( doit ) 4: { 5: return( val + incr ); 6: } 7: return( val ); 8: }
to:
1: int add( int val, int incr, int doit ) 2: { 3: if( doit ) 4: { 5: return( val + incr ); 6: } 7: return( val ); 8: }
In other words, we want to change the indentation of braces that open a block following a condition so that the braces line up under the conditional, instead of being indented. Notice that the construct we want to change starts on line 4. To change the indentation of a line, we need to see which syntactic component affect the offset calculations for that line. Hitting C-c C-s on line 4 yields:
((substatement-open . 46))
so we know that to change the offset of the open brace, we need to
change the indentation for the substatement-open
syntactic
symbol. To do this interactively, just hit C-c C-o
(c-set-offset
). This prompts you for the syntactic symbol to
change, providing a reasonable default. In this case, the default is
substatement-open
, which is just the syntactic symbol we want to
change!
After you hit return, cc-mode
will then prompt you for the new
offset value, with the old value as the default. The default in this
case is `+', so hit backspace to delete the `+', then hit
`0' and RET. This will associate the offset 0 with the
syntactic symbol substatement-open
in the c-offsets-alist
variable.
To check your changes quickly, just hit C-c C-q
(c-indent-defun
) to reindent the entire function. The example
should now look like:
1: int add( int val, int incr, int doit ) 2: { 3: if( doit ) 4: { 5: return( val + incr ); 6: } 7: return( val ); 8: }
Notice how just changing the open brace offset on line 4 is all we needed to do. Since the other affected lines are indented relative to line 4, they are automatically indented the way you'd expect. For more complicated examples, this may not always work. The general approach to take is to always start adjusting offsets for lines higher up in the file, then re-indent and see if any following lines need further adjustments.
To make this change permanent, you need to add some lisp code to your
`.emacs' file. cc-mode
provides four hooks that you can use
to customize your language editing styles. Four language specific hooks
are provided, according to Emacs major mode conventions:
c-mode-hook
, c++-mode-hook
, objc-mode-hook
, and
java-mode-hook
. These get run as the last thing when you enter
c-mode
, c++-mode
, objc-mode
, or
java-mode-hook
respectively. cc-mode
also provides a hook
called c-mode-common-hook
which is run by all three modes
before the language specific hook. Thus, to make changes
consistently across all supported cc-mode
modes, use
c-mode-common-hook
. Most of the examples in this section will
assume you are using the common hook.
Here's a simplified example of what you can add to your `.emacs' file to make the changes described in the previous section (section Interactive Customization) more permanent. See the Emacs manuals for more information on customizing Emacs via hooks. See section Sample `.emacs' file for a more complete sample `.emacs' file. (10)
(defun my-c-mode-common-hook () ;; my customizations for all of c-mode, c++-mode, objc-mode, java-mode (c-set-offset 'substatement-open 0) ;; other customizations can go here ) (add-hook 'c-mode-common-hook 'my-c-mode-common-hook)
For complex customizations, you will probably want to set up a style that groups all your customizations under a single name.
The offset value can also be a function, and this is how power users gain enormous flexibility in customizing indentation. See section Advanced Customizations for details.
Most people only need to edit code formatted in just a few well-defined
and consistent styles. For example, their organization might impose a
"blessed" style that all its programmers must conform to. Similarly,
people who work on GNU software will have to use the GNU coding style on
C code. Some shops are more lenient, allowing some variety of coding
styles, and as programmers come and go, there could be a number of
styles in use. For this reason, cc-mode
makes it convenient for
you to set up logical groupings of customizations called styles,
associate a single name for any particular style, and pretty easily
start editing new or existing code using these styles. This chapter
describes how to set up styles and how to edit your C code using styles.
If you're lucky, one of cc-mode
's built-in styles might be just
what you're looking for. Some of the most common C and C++ styles are
already built-in. These include:
gnu
-- coding style blessed by the Free Software Foundation
for C code in GNU programs.
k&r
-- The classic Kernighan and Ritchie style for C code.
bsd
-- <TBD> Anybody know anything about the history of
this style?
stroustrup
-- The classic Stroustrup style for C++ code.
whitesmith
-- <TBD> Anybody know anything about the history of
this style?
ellemtel
-- Popular C++ coding standards as defined by
"Programming in C++, Rules and Recommendations", Erik Nyquist and Mats
Henricson, Ellemtel (11).
java
-- The style for editing Java code. Note that this style is
automatically installed when you enter java-mode
.
CC-MODE
-- Style that encapsulates the default values of the
cc-mode
variables. See below for details.
If you'd like to experiment with these built-in styles you can simply
type the following in a cc-mode
buffer:
M-x c-set-style RET STYLE-NAME RET
Note that all style names are case insensitive, even the ones you define.
Setting a style in this way does not automatically re-indent your file. For commands that you can use to view the effect of your changes, see section Indentation Commands.
Once you find a built-in style you like, you can make the change
permanent by adding a call to your `.emacs' file. Let's say for
example that you want to use the ellemtel
style in all your
files. You would add this:
(defun my-c-mode-common-hook () ;; use Ellemtel style for all C, C++, and Objective-C code (c-set-style "ellemtel") ;; other customizations can go here ) (add-hook 'c-mode-common-hook 'my-c-mode-common-hook)
There is one other special style you can use, called CC-MODE
.
This is a style that is calculated by cc-mode
when it starts up.
The CC-MODE
style is also special because all other styles
implicitly inherit from it; in other words, whenever you set a style,
cc-mode
first re-instates the CC-MODE
style, then applies
your new style configurations.
The CC-MODE
style exists because once cc-mode
initializes,
it institutes the gnu
style for compatibility with BOCM's
defaults. Any customizations you make in mode hooks will be based on
the gnu
style, unless you first do a c-set-style
to
CC-MODE
or some other built-in style.
If none of the built-in styles is appropriate, you'll probably want to
add a new style definition. Styles are kept in the c-style-alist
variable, but you probably won't want to modify this variable directly.
cc-mode
provides a function, called c-add-style
, that you
can use to easily add new styles or update existing styles. This
function takes two arguments, a stylename string, and an
association list description of style customizations. If
stylename is not already in c-style-alist
, the new style is
added, otherwise the style already associated with stylename is
changed to the new description. This function also takes an
optional third argument, which if non-nil
, automatically
institutes the new style in the current buffer.
The sample `.emacs' file provides a concrete example of how a new style can be added and automatically set. See section Sample `.emacs' file.
The Emacs manual describes how you can customize certain variables on a
per-file basis by including a Local Variable block at the end of
the file. So far, you've only seen a functional interface to
cc-mode
, which is highly inconvenient for use in a Local Variable
block. cc-mode
provides two variables that make it easier for
you to customize your style on a per-file basis.
The variable c-file-style
can be set to a style name string as
described in section Built-in Styles. When the file is visited,
cc-mode
will automatically set the file's style to this style
using c-set-style
.
Another variable, c-file-offsets
, takes an association list
similar to what is allowed in c-offsets-alist
. When the file is
visited, cc-mode
will automatically institute these offsets using
c-set-offset
.
Note that file style settings (i.e. c-file-style
) are applied
before file offset settings (i.e. c-file-offsets
).
For most users, cc-mode
will support their coding styles with
very little need for customizations. Usually, one of the standard
styles defined in c-style-alist
will do the trick. At most,
perhaps one of the syntactic symbol offsets will need to be tweaked
slightly, or maybe c-basic-offset
will need to be changed.
However, some styles require a more advanced ability for customization,
and one of the real strengths of cc-mode
is that the syntactic
analysis model provides a very flexible framework for customizing
indentation. This allows you to perform special indentation calculations
for situations not handled by the mode directly.
One of the most common ways to customize cc-mode
is by writing
custom indentation functions and associating them with specific
syntactic symbols (see section Syntactic Symbols). cc-mode
itself
uses custom indentation functions to provide more sophisticated
indentation, for example when lining up C++ stream operator blocks:
1: void main(int argc, char**) 2: { 3: cout << "There were " 4: << argc 5: << "arguments passed to the program" 6: << endl; 7: }
In this example, lines 4 through 6 are assigned the stream-op
syntactic symbol. If stream-op
had an offset of +
, and
c-basic-offset
was 2, lines 4 through 6 would simply be indented
two spaces to the right of line 3. But perhaps we'd like cc-mode
to be a little more intelligent so that it offsets the stream operators
under the operator in line 3. To do this, we have to write a custom
indentation function which finds the column of first stream operator on
the first line of the statement. Here is the lisp code (from the
`cc-mode.el' source file) that implements this:
(defun c-lineup-streamop (langelem) ;; lineup stream operators (save-excursion (let* ((relpos (cdr langelem)) (curcol (progn (goto-char relpos) (current-column)))) (re-search-forward "<<\\|>>" (c-point 'eol) 'move) (goto-char (match-beginning 0)) (- (current-column) curcol))))
Custom indent functions take a single argument, which is a syntactic
component cons cell (see section Syntactic Analysis). The
function returns an integer offset value that will be added to the
running total indentation for the line. Note that what actually gets
returned is the difference between the column that the first stream
operator is on, and the column of the buffer relative position passed in
the function's argument. Remember that cc-mode
automatically
adds in the column of the component's relative buffer position and we
don't want that value added into the final total twice.
Now, to associate the function c-lineup-streamop
with the
stream-op
syntactic symbol, we can add something like the
following to our c++-mode-hook
(12):
(c-set-offset 'stream-op 'c-lineup-streamop)
Now the function looks like this after re-indenting (using C-c C-q):
1: void main(int argc, char**) 2: { 3: cout << "There were " 4: << argc 5: << "arguments passed to the program" 6: << endl; 7: }
Custom indentation functions can be as simple or as complex as you like,
and any syntactic symbol that appears in c-offsets-alist
can have
a custom indentation function associated with it.
Syntactic symbols aren't the only place where you can customize
cc-mode
with the lisp equivalent of callback functions. Brace
hanginess can also be determined by custom functions associated with
syntactic symbols on the c-hanging-braces-alist
variable.
Remember that ACTION's are typically a list containing some
combination of the symbols before
and after
(see
section Hanging Braces). However, an ACTION can also be a function
symbol which gets called when a brace matching that syntactic symbol is
typed.
These ACTION functions are called with two arguments: the
syntactic symbol for the brace, and the buffer position at which the
brace was inserted. The ACTION function is expected to return a
list containing some combination of before
and after
. The
function can also return nil
. This return value has the normal
brace hanging semantics described in section Hanging Braces.
As an example, cc-mode
itself uses this feature to dynamically
determine the hanginess of braces which close `do-while'
constructs:
void do_list( int count, char** atleast_one_string ) { int i=0; do { handle_string( atleast_one_string( i )); i++; } while( i < count ); }
cc-mode
assigns the block-close
syntactic symbol to the
brace that closes the do
construct, and normally we'd like the
line that follows a block-close
brace to begin on a separate
line. However, with `do-while' constructs, we want the
while
clause to follow the closing brace. To do this, we
associate the block-close
symbol with the ACTION function
c-snug-do-while
:
(defun c-snug-do-while (syntax pos) "Dynamically calculate brace hanginess for do-while statements. Using this function, `while' clauses that end a `do-while' block will remain on the same line as the brace that closes that block. See `c-hanging-braces-alist' for how to utilize this function as an ACTION associated with `block-close' syntax." (save-excursion (let (langelem) (if (and (eq syntax 'block-close) (setq langelem (assq 'block-close c-syntactic-context)) (progn (goto-char (cdr langelem)) (if (= (following-char) ?{) (forward-sexp -1)) (looking-at "\\<do\\>[^_]"))) '(before) '(before after)))))
This function simply looks to see if the brace closes a `do-while'
clause and if so, returns the list `(before)
' indicating
that a newline should be inserted before the brace, but not after it.
In all other cases, it returns the list `(before after)
' so
that the brace appears on a line by itself.
During the call to the brace hanging ACTION function, the variable
c-syntactic-context
is bound to the full syntactic analysis list.
Note that for symmetry, colon hanginess should be customizable by
allowing function symbols as ACTIONs on the
c-hanging-colon-alist
variable. Since no use has actually been
found for this feature, it isn't currently implemented.
You can also customize the insertion of newlines after semi-colons and
commas, when the auto-newline minor mode is enabled (see section Minor Modes). This is controlled by the variable
c-hanging-semi&comma-criteria
, which contains a list of functions
that are called in the order they appear. Each function is called with
zero arguments, and is expected to return one of the following values:
nil
-- A newline is inserted, and no more functions from the
list are called.
stop
-- No more functions from the list are called, but no
newline is inserted.
nil
-- No determination is made, and the next function in the
list is called.
If every function in the list is called without a determination being
made, then no newline is added. The default value for this variable is a
list containing a single function which inserts newlines only after
semi-colons which do not appear inside parenthesis lists (i.e. those
that separate for
-clause statements).
One other customization variable is available in cc-mode
:
c-special-indent-hook
. This is a standard hook variable that is
called after every line is indented by cc-mode
. You can use it
to do any special indentation or line adjustments your style dictates,
such as adding extra indentation to constructors or destructor
declarations in a class definition, etc. Note however, that you should
not change point or mark inside your c-special-indent-hook
functions (i.e. you'll probably want to wrap your function in a
save-excursion
).
Go to the first, previous, next, last section, table of contents.