[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9. Customizing Indentation

The context sensitive indentation is mainly controlled by the variable c-offsets-alist:

User Option: c-offsets-alist
This special style variable contains the mappings between syntactic symbols and the offsets to apply for those symbols. It's set at mode initialization from a style you may specify. Styles are groupings of syntactic symbol offsets and other style variable values. Most likely, you'll find that one of the predefined styles will suit your needs. See section 9.4 Styles, for an explanation of how to set up named styles.

Only syntactic symbols not already bound on c-offsets-alist will be set from styles. This means that any association you set on it, be it before or after mode initialization, will not be changed. The c-offsets-alist variable may therefore be used from e.g. the Customization interface(16) to easily change indentation offsets without having to bother about styles. Initially c-offsets-alist is empty, so that all syntactic symbols are set by the style system.

The offset associated with any particular syntactic symbol can be an integer, a function or lambda expression, a variable name, a vector, a list, or one of the following special symbols: +, -, ++, --, *, or /. The meaning of these values are described in detail below.

The special symbols describe an offset in multiples of the value of c-basic-offset:

User Option: c-basic-offset
Style variable that holds the basic offset between indentation levels.

By defining a style's indentation in terms of c-basic-offset, you can change the amount of whitespace given to an indentation level while maintaining the same basic shape of your code. 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

When a function is used as offset, it's called an indentation function. Such functions are useful when more context than just the syntactic symbol is needed to get the desired indentation. See section 11. Indentation Functions, and 9.5.1 Custom Indentation Functions, for details about them.

If the offset is a vector, its first element sets the absolute indentation column, which will override any previous relative indentation. It won't override additional relative indentation for nested constructs, though.

The offset can also be a list, in which case it is evaluated recursively using the semantics described above. The first element of the list that returns a non-nil value succeeds and the evaluation stops. If none of the list elements return a non-nil value, then an offset of 0 (zero) is used(17).

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(18):

M-x set-variable RET
Set variable: c-basic-offset RET
Set c-basic-offset to value: 4 RET

This would change

int add( int val, int incr, int doit )
  if( doit )
      return( val + incr );
  return( val );


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 offsets associated with other syntactic symbols. 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.

9.1 Interactive Customization  
9.2 Permanent Customization  
9.3 Hooks  
9.4 Styles  
9.5 Advanced Customizations  

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.1 Interactive Customization

As an example of how to customize indentation, let's change the style of this example(19):

 1: int add( int val, int incr, int doit )
 2: {
 3:   if( doit )
 4:     {
 5:       return( val + incr );
 6:     }
 7:   return( val );
 8: }


 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. 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 `+', but we want no extra indentation so enter `0' and RET. This will associate the offset 0 with the syntactic symbol substatement-open.

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 reindent and see if any following lines need further adjustments.

Command: c-set-offset symbol offset
This is the command bound to C-c C-o. It provides a convenient way to set offsets on c-offsets-alist both interactively (see the example above) and from your mode hook.

It takes two arguments when used programmatically: symbol is the syntactic element symbol to change and offset is the new offset for that syntactic element.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.2 Permanent Customization

To make your changes permanent, you need to add some lisp code to your `.emacs' file. CC Mode supports many different ways to be configured, from the straightforward way by setting variables globally in `.emacs' or in the Customization interface, to the complex and precisely controlled way by using styles and hook functions.

The simplest way of customizing CC Mode permanently is to set the variables in your `.emacs' with setq and similar commands. So to make a permanent setting of substatement-open to 0, add this to the `.emacs' file:

(setq c-offsets-alist
      '((substatement-open . 0)))

When CC Mode initializes a buffer, it will fill out c-offsets-alist with the remaining syntactic symbols according to the style system.

You can also use the more user friendly Customization interface, but this manual does not cover how that works.

Variables set like this at the top level in `.emacs' take effect in all CC Mode buffers, regardless of language. The indentation style related variables, e.g. c-offsets-alist, that you don't set this way get their value from the style system (see section 9.4 Styles), and they therefore depend on the setting of c-default-style. Note that if you use Customize, this means that the greyed-out default values presented there might not be the ones you actually get, since the actual values depend on the style, which may very well be different for different languages.

If you want to make more advanced configurations, e.g. language-specific customization, setting global variables isn't enough. For that you can use the language hooks, see 9.3 Hooks, and/or the style system, see 9.4 Styles.

User Option: c-style-variables-are-local-p
By default, all style variables are buffer local, so that different buffers can have different style settings. If you only use one style in all the files you edit you might want to share them between buffers so that a change take effect in all buffers. That's done by setting this variable to nil. The value takes effect when CC Mode is activated in a buffer for the first time in the Emacs session, so you typically set it in your `.emacs' file and then restart Emacs.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.3 Hooks

CC Mode 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:

Variable: c-initialization-hook
Hook run only once per Emacs session, when CC Mode is initialized.

Variable: c-mode-common-hook
Common hook across all languages. It's run immediately before the language specific hook.

Variable: c-mode-hook
Variable: c++-mode-hook
Variable: objc-mode-hook
Variable: java-mode-hook
Variable: idl-mode-hook
Variable: pike-mode-hook
Variable: awk-mode-hook
The language specific mode hooks. The appropriate one is run as the last thing when you enter that language mode.

Note that all the language-specific mode setup that CC Mode does is done prior to both c-mode-common-hook and the language specific hook. That includes installing the indentation style, which can be mode specific (and also is by default for Java mode). Thus, any style settings done in c-mode-common-hook will override whatever language-specific style is chosen by c-default-style.

Here's a simplified example of what you can add to your `.emacs' file to do things whenever any CC Mode language is edited. See the Emacs manuals for more information on customizing Emacs via hooks. See section D. 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
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.4 Styles

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. 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, 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.

The variables that the style system affect are called style variables. They are handled specially in several ways:

The style variables are: 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-backslash-max-column, c-special-indent-hook, c-label-minimum-indentation, and c-offsets-alist.

9.4.1 Built-in Styles  
9.4.2 Choosing a Style  
9.4.3 Adding and Amending Styles  
9.4.4 File Styles  

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.4.1 Built-in Styles

If you're lucky, one of CC Mode's built-in styles might be just what you're looking for. These include:

Coding style blessed by the Free Software Foundation for C code in GNU programs.

The classic Kernighan and Ritchie style for C code.

Also known as "Allman style" after Eric Allman.

Popularized by the examples that came with Whitesmiths C, an early commercial C compiler.

The classic Stroustrup style for C++ code.

Popular C++ coding standards as defined by "Programming in C++, Rules and Recommendations," Erik Nyquist and Mats Henricson, Ellemtel(22).

C coding standard for Linux (the kernel).

C coding standard for Python extension modules(23).

The style for editing Java code. Note that the default value for c-default-style installs this style when you enter java-mode.

This is a special style for several reasons. First, the CC Mode customizations you do by using either the Customization interface, or by writing setq's at the top level of your `.emacs' file, will be captured in the user style. Also, all other styles implicitly inherit their settings from user style. This means that for any styles you add via c-add-style (see section 9.4.3 Adding and Amending Styles) you need only define the differences between your new style and user style.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.4.2 Choosing a Style

Use C-c . to choose a style interactively:

Command: c-set-style style-name
Switch to the specified style in the current buffer. Use interactively like this:

C-c . 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 reindent your file. For commands that you can use to view the effect of your changes, see 8. Commands.

The default style in all newly created buffers is gnu, except in Java mode where it's java. Although the user style is not the default style, any style variable settings you do with the Customization interface or on the top level in your `.emacs' file will by default override the style system, so you don't need to set c-default-style to user to see the effect of such settings.

User Option: c-default-style
This variable specifies which style to install by default in new buffers. It takes either a style name string, or an association list of major mode symbols to style names:

  1. When c-default-style is a string, it must be an existing style name. This style is then used for all modes.

  2. When c-default-style is an association list, the mode language is looked up to find a style name string.

  3. If c-default-style is an association list where the mode language mode isn't found then the special symbol `other' is looked up. If it's found then the associated style is used.

  4. If `other' is not found then the `gnu' style is used.

  5. In all cases, the style described in c-default-style is installed before the language hooks are run, so you can always override this setting by including an explicit call to c-set-style in your language mode hook, or in c-mode-common-hook.

Variable: c-indentation-style
This variable always contains the buffer's current style name, as a string.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.4.3 Adding and Amending Styles

If none of the built-in styles is appropriate, you'll probably want to create a new style definition, possibly based on an existing style. To do this, put the new style's settings into a list with the following format - the list can then be passed as an argument to the function c-add-style:

List: style definition
([base-style] [(variable . value) ...])

Optional base-style, if present, must be a string which is the name of the base style from which this style inherits. At most one base-style is allowed in a style definition. If base-style is not specified, the style inherits from a table of default values(24) instead. All styles eventually inherit from this internal table. Style loops generate errors. The list of pre-existing styles can be seen in 9.4.1 Built-in Styles.

The dotted pairs (variable . value) each consist of a variable and the value it is to be set to when the style is later activated.(25) The variable can be either a CC Mode style variable or an arbitrary Emacs variable. In the latter case, it is not made buffer local by the CC Mode style system.

Two variables are treated specially in the dotted pair list:

The value is in turn a dotted list on the form

(syntactic-symbol . offset)

as described in 9. Customizing Indentation. These are passed to c-set-offset so there is no need to set every syntactic symbol in your style, only those that are different from the inherited style.

The value is added to c-special-indent-hook using add-hook, so any functions already on it are kept. If the value is a list, each element of the list is added with add-hook.

Styles are kept in the c-style-alist variable, but you should never modify this variable directly. Instead, CC Mode provides the function c-add-style for this purpose.

Function: c-add-style stylename description &optional set-p
Add or update a style called stylename, a string. description is the new style definition in the form described above. If stylename already exists in c-style-alist then it is replaced by description. (Note, this replacement is total. The old style is not merged into the new one.) Otherwise, a new style is added. If the optional set-p is non-nil then the new style is applied to the current buffer as well.

The sample `.emacs' file provides a concrete example of how a new style can be added and automatically set. See section D. Sample .emacs file.

Variable: c-style-alist
This is the variable that holds the definitions for the styles. It should not be changed directly; use c-add-style instead.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.4.4 File Styles

The Emacs manual describes how you can customize certain variables on a per-file basis by including a file local variable block at the end of the file. So far, you've only seen a functional interface to CC Mode customization, which can't be used there. CC Mode provides two variables allow customization of the indentation style on a per-file basis:

Variable: c-file-style
This variable can be set to a style name string. When the file is visited, CC Mode will automatically set the file's style to this one using c-set-style.

Variable: c-file-offsets
This variable 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). Also, if either of these are set in a file's local variable section, all the style variable values are made local to that buffer.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.5 Advanced Customizations

For most users, CC Mode will support their coding styles with very little need for more advanced customizations. Usually, one of the standard styles (see section 9.4.1 Built-in Styles) 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 CC Mode 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.

9.5.1 Custom Indentation Functions  
9.5.2 Custom Brace and Colon Hanging  
9.5.3 Customizing Semicolons and Commas  
9.5.4 Other Special Indentations  

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.5.1 Custom Indentation Functions

The most flexible way to customize CC Mode is by writing custom indentation functions, and associating them with specific syntactic symbols (see section 10. Syntactic Symbols). CC Mode itself uses 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 CC Mode 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 the first stream operator on the first line of the statement. Here is sample lisp code implementing this:

(defun c-lineup-streamop (langelem)
    (goto-char (cdr langelem))
    (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
    (goto-char (match-beginning 0))
    (vector (current-column))))

Indentation functions take a single argument, which is a syntactic component cons cell (see section 3.1 Syntactic Analysis). The function can return an integer which is added to the running total indentation for the line, or a vector containing an integer which is an absolute column to align to. Usually an absolute column is wanted when aligning to existing text, as in this example.

The function should return nil if it's used in a situation where it doesn't want to make any decision. If the function is used in a list expression (see section 9. Customizing Indentation), that will cause CC Mode to go on and check the next entry in the list.

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(26):

(c-set-offset 'stream-op 'c-lineup-streamop)

Now the function looks like this after reindenting (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.

CC Mode comes with an extensive set of predefined indentation functions, not all of which are used by the default styles. So there's a good chance the function you want already exists. See section 11. Indentation Functions, for a list of them. If you have written an indentation function that you think is generally useful, you're very welcome to contribute it; please contact bug-cc-mode@gnu.org.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.5.2 Custom Brace and Colon Hanging

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 style variable. Remember that action's are typically a list containing some combination of the symbols before and after (see section 4.1.1 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, including neither of them (i.e. nil). This return value has the normal brace hanging semantics.

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] );
    } 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."
    (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 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.

Variable: c-syntactic-context
During the call to the indentation or brace hanging action function, this variable 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-colons-alist style variable. Since no use has actually been found for this feature, it isn't currently implemented!

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.5.3 Customizing Semicolons and Commas

You can also customize the insertion of newlines after semicolons and commas when the auto-newline minor mode is enabled (see section 4. Minor Modes).

User Option: c-hanging-semi&comma-criteria
This style variable takes a list of hooks that get called when a semicolon or comma is inserted. The hooks are called in order without arguments, and are expected to return one of the following values:

A newline is inserted, and no more functions from the list are called.
No more functions from the list are called, but no newline is inserted.
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 semicolons which do not appear inside parenthesis lists (i.e. those that separate for-clause statements).

Function: c-semi&comma-no-newlines-before-nonblanks
This is an example of a criteria function, provided by CC Mode. It prevents newlines from being inserted after semicolons when there is a non-blank following line. Otherwise, it makes no determination. To use, add this function to the front of the c-hanging-semi&comma-criteria list.

(defun c-semi&comma-no-newlines-before-nonblanks ()
    (if (and (eq last-command-char ?\;)
             (zerop (forward-line 1))
             (not (looking-at "^[ \t]*$")))

Function: c-semi&comma-inside-parenlist
Function: c-semi&comma-no-newlines-for-oneline-inliners
The function c-semi&comma-inside-parenlist is what prevents newlines from being inserted inside the parenthesis list of for statements. In addition to c-semi&comma-no-newlines-before-nonblanks described above, CC Mode also comes with the criteria function c-semi&comma-no-newlines-for-oneline-inliners, which suppresses newlines after semicolons inside one-line inline method definitions (e.g. in C++ or Java).

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.5.4 Other Special Indentations

Here are the remaining odds and ends regarding indentation:

User Option: c-label-minimum-indentation
In `gnu' style (see section 9.4.1 Built-in Styles), a minimum indentation is imposed on lines inside top-level constructs. This minimum indentation is controlled by this style variable. The default value is 1.

User Option: c-special-indent-hook
This style variable 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 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.

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by XEmacs Webmaster on October, 2 2007 using texi2html