ccmode: Indentation Calculation

 
 10.3 Indentation Calculation
 ============================
 
 Indentation for a line is calculated from the syntactic context (See
 Syntactic Analysis).
 
    First, a buffer position is found whose column will be the base for
 the indentation calculation.  It’s the anchor position in the first
 syntactic element that provides one that is used.  If no syntactic
 element has an anchor position then column zero is used.
 
    Second, the syntactic symbols in each syntactic element are looked up
 in the ‘c-offsets-alist’ style variable (Seec-offsets-alist), which
 is an association list of syntactic symbols and the offsets to apply for
 those symbols.  These offsets are added together with the base column to
 produce the new indentation column.
 
    Let’s use our two code examples above to see how this works.  Here is
 our first example again:
 
       1: void swap( int& a, int& b )
       2: {
       3:     int tmp = a;
       4:     a = b;
       5:     b = tmp;
       6: }
 
    Let’s say point is on line 3 and we hit the <TAB> key to reindent the
 line.  The syntactic context for that line is:
 
      ((defun-block-intro 29))
 
 Since buffer position 29 is the first and only anchor position in the
 list, CC Mode goes there and asks for the current column.  This brace is
 in column zero, so CC Mode uses ‘0’ as the base column.
 
    Next, CC Mode looks up ‘defun-block-intro’ in the ‘c-offsets-alist’
 style variable.  Let’s say it finds the value ‘4’; it adds this to the
 base column ‘0’, yielding a running total indentation of 4 spaces.
 
    Since there is only one syntactic element on the list for this line,
 indentation calculation is complete, and the total indentation for the
 line is 4 spaces.
 
    Here’s another example:
 
       1: int add( int val, int incr, int doit )
       2: {
       3:     if( doit )
       4:         {
       5:             return( val + incr );
       6:         }
       7:     return( val );
       8: }
 
    If we were to hit ‘TAB’ on line 4 in the above example, the same
 basic process is performed, despite the differences in the syntactic
 context.  The context for this line is:
 
      ((substatement-open 46))
 
    Here, CC Mode goes to buffer position 46, which is the ‘i’ in ‘if’ on
 line 3.  This character is in the fourth column on that line so the base
 column is ‘4’.  Then CC Mode looks up the ‘substatement-open’ symbol in
 ‘c-offsets-alist’.  Let’s say it finds the value ‘4’.  It’s added with
 the base column and yields an indentation for the line of 8 spaces.
 
    Simple, huh?
 
    Actually, it’s a bit more complicated than that since the entries on
 ‘c-offsets-alist’ can be much more than plain offsets.  See
 c-offsets-alist, for the full story.
 
    Anyway, the mode usually just does The Right Thing without you having
 to think about it in this much detail.  But when customizing
 indentation, it’s helpful to understand the general indentation model
 being used.
 
    As you configure CC Mode, you might want to set the variable
 ‘c-echo-syntactic-information-p’ to non-‘nil’ so that the syntactic
 context and calculated offset always is echoed in the minibuffer when
 you hit ‘TAB’.