The variable c-offsets-alist
contains the mappings between
syntactic symbols and the offsets to apply for those symbols. You
should never modify this variable directly though. Use the function
c-set-offset
instead (see below for details).
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
indentatio. 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 of syntactic symbols and the offsets to be applied for
those symbols. In fact, these offset values can be any of an integer, a
function or lambda expression, a 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 the values 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):
(setq 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 this example(20):
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 components affect the offset calculations for that line. Hitting C-c C-s on line 4 yields:
((substatement-open . 44))
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, @ccmode{} will then prompt you for the new
offset value, with the old value as the default. The default in this
case is `+', but we want no extra indentation so enter
`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 your changes permanent, you need to add some lisp code to your `.emacs' file, but first you need to decide whether your styles should be global in every buffer, or local to each specific buffer.
If you edit primarily one style of code, you may want to make the @ccmode{} style variables have global values so that every buffer will share the style settings. This will allow you to set the @ccmode{} variables at the top level of your `.emacs' file, and is the way @ccmode{} works by default.
If you edit many different styles of code at
the same time, you might want to make the @ccmode{} style variables
have buffer local values. If you do this, then you will need to set any
@ccmode{} style variables in a hook function (e.g. off of
c-mode-common-hook
instead of at the top level of your
`.emacs' file. The recommended way to do this is to set the
variable c-style-variables-are-local-p
to t
before @ccmode{} is loaded into your Emacs session.
@ccmode{} provides several hooks that you can use to customize the mode according to your coding style. Each language mode has its own hook, adhering to standard Emacs major mode conventions. There is also one general hook and one package initialization hook:
c-mode-hook
-- for C buffers only
c++-mode-hook
-- for C++ buffers only
objc-mode-hook
-- for Objective-C buffers only
java-mode-hook
-- for Java buffers only
idl-mode-hook
-- for IDL buffers only
c-mode-common-hook
-- common across all languages
c-initialization-hook
-- hook run only once per Emacs session,
when @ccmode{} is initialized.
The language hooks get run as the last thing when you enter that
language mode. The c-mode-common-hook
is run by all
supported modes before the language specific hook, and thus can
contain customizations that are common across all languages. Most of
the examples in this section will assume you are using the common
hook(21).
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.
(defun my-c-mode-common-hook () ;; my customizations for all of c-mode and related modes (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.
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 a variety of coding styles, and as programmers come and go, there could be a number of styles in use. For this reason, @ccmode{} 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 section describes how to set up styles and how to edit your C code using styles.
If you're lucky, one of @ccmode{}'s built-in styles might be just what you're looking for. 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
-- Also known as "Allman style" after Eric Allman.
whitesmith
-- Popularized by the examples that came with
Whitesmiths C, an early commercial C compiler.
stroustrup
-- The classic Stroustrup style for C++ code.
ellemtel
-- Popular C++ coding standards as defined by
"Programming in C++, Rules and Recommendations", Erik Nyquist and Mats
Henricson, Ellemtel (22).
linux
-- C coding standard for Linux development.
python
-- C coding standard for Python extension
modules(23).
java
-- The style for editing Java code. Note that this style is
automatically installed when you enter java-mode
.
If you'd like to experiment with these built-in styles you can simply type the following in a @ccmode{} buffer:
C-c . STYLE-NAME RET
C-c . runs the command c-set-style
. 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 Commands.
Once you find a built-in style you like, you can make the change permanent by adding some lisp 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 like languages (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' style. This style is special because all other styles implicitly inherit from it; in other words, whenever you set a style, `cc-mode' is applied before the one you selected. This means your style need only define the differences between it and `cc-mode' style.
Note you should never change any of the default styles.
Instead, it's better to add a new style using c-add-style
(See section Adding Styles). This is especially true for cc-mode
and
java
styles.
Note that for BOCM compatibility, `gnu' is the default
style, and any non-style based customizations you make (i.e. in
c-mode-common-hook
in your
`.emacs' file) will be based on `gnu' style unless you do
a c-set-style
as the first thing in your hook. The variable
c-indentation-style
always contains the buffer's current style name,
as a string.
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 should never modify this variable
directly. Instead, @ccmode{} provides the function
c-add-style
that you can use to easily add new styles or change
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 is
changed to the new description.
This function also takes an optional third argument, which if
non-nil
, automatically applies the new style to 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 @ccmode{} customization, which is highly inconvenient for use in a Local Variable block. @ccmode{} provides two variables that make it easier for you to customize your style on a per-file basis(24)
The variable c-file-style
can be set to a style name string.
When the file is visited, @ccmode{} 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, @ccmode{} will automatically institute these offets 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, @ccmode{} will support their coding styles with
very little need for more advanced 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 flexible framework for
customization, and one of the real strengths of @ccmode{} is that
the syntactic analysis model provides just such a framework. This allows
you to implement custom indentation calculations for situations not
handled by the mode directly.
Note that the style controlling variables can either have global values,
or can be buffer local (e.g. different in every buffer). If all the C
files you edit tend to have the same style, you might want to keep the
variables global. If you tend to edit files with many different styles,
you will have to make the variables buffer local. The variable
c-style-variables-are-local-p
controls this.
When c-style-variables-are-local-p
is non-nil, then the style
variables will have a different settable value for each buffer,
otherwise all buffers will share the same values. By default, its value
is nil
(i.e. global values). You must set this variable
before @ccmode{} is loaded into your Emacs session, and once the
variables are made buffer local, they cannot be made global again
(unless you restart Emacs of course!)
The most flexible way to customize @ccmode{} is by writing @dfn{custom indentation functions} and associating them with specific syntactic symbols (see section Syntactic Symbols). @ccmode{} 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. Here, stream-op
has an offset of +
, and
with a c-basic-offset
of 2, you can see that lines 4 through 6
are simply indented two spaces to the right of line 3. But perhaps we'd
like @ccmode{} to be a little more intelligent so that it aligns
all the `<<' symbols in lines 3 through 6. 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 sample
lisp code implementing 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 @ccmode{} automatically adds in the column of the component's relative buffer position and we don't the column offset added in 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
(25):
(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. @ccmode{} comes
with several standard custom indentation functions, not all of which are
used by the default styles.
c-lineup-arglist
-- lines up function argument lines under the
argument on the previous line.
c-lineup-arglist-intro-after-paren
-- similar to
c-lineup-arglist
, but works for argument lists that begin with an
open parenthesis followed by a newline.
c-lineup-arglist-close-under-paren
-- set your
arglist-close
syntactic symbol to this line-up function so that
parentheses that close argument lists will line up under the parenthesis
that opened the argument list.
c-lineup-streamop
-- lines up C++ stream operators
(e.g. `<<' and `>>').
c-lineup-multi-inher
-- lines up multiple inheritance lines.
c-lineup-C-comments
-- lines up C block comment continuation
lines.
c-lineup-comment
-- lines up comment only lines according to
the variable c-comment-only-line-offset
.
c-lineup-runin-statements
-- lines up statement
s for coding
standards which place the first statement in a block on the same line as
the block opening brace(26).
c-lineup-math
-- lines up math statement-cont
lines under
the previous line after the equals sign.
c-lineup-ObjC-method-call
-- for Objective-C code, lines up
selector arguments just after the message receiver.
c-lineup-ObjC-method-args
-- for Objective-C code, lines up the
colons that separate arguments by aligning colons vertically.
c-lineup-ObjC-method-args-2
-- similar to
c-lineup-ObjC-method-args
but lines up the colon on the current
line with the colon on the previous line.
Syntactic symbols aren't the only place where you can customize
@ccmode{} 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
which gets called when a brace matching that syntactic symbol is
entered.
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.
As an example, @ccmode{} 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 ); }
@ccmode{} 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).
Here's an example of a criteria function that will prevent newlines from
being inserted after semicolons when there is a non-blank following
line. Otherwise, it makes no determination. To use, add this to the
front of the c-hanging-semi&comma-criteria
list.
(defun my-semicolon-criteria () (save-excursion (if (and (eq last-command-char ?\;) (zerop (forward-line 1)) (not (looking-at "^[ \t]*$"))) 'stop nil)))
In `gnu' style (see section Built-in Styles), a minimum indentation
is imposed on lines inside top-level constructs. This minimum
indentation is controlled by the variable
c-label-minimum-indentation
. The default value for this variable
is 1.
One other customization variable is available in @ccmode{}:
c-special-indent-hook
. This is a standard hook variable that is
called after every line is indented by @ccmode{}. 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
).
Setting c-special-indent-hook
in your style definition is handled
slightly differently than other variables. In your style definition,
you should set the value for
c-special-indent-hook
to a function or list of functions, which
will be appended to c-special-indent-hook
using add-hook
.
That way, the current setting for the buffer local value of
c-special-indent-hook
won't be overridden.
Normally, the standard Emacs command M-;
(indent-for-comment
) will indent comment only lines to
comment-column
. Some users however, prefer that M-; act
just like TAB for purposes of indenting comment-only lines;
i.e. they want the comments to always indent as they would for normal
code, regardless of whether TAB or M-; were used. This
behavior is controlled by the variable
c-indent-comments-syntactically-p
. When nil
(the
default), M-; indents comment-only lines to comment-column
,
otherwise, they are indented just as they would be if TAB were
typed.
Go to the first, previous, next, last section, table of contents.