Syntactic Analysis
New Indentation Engine
Indentation for a line is calculated using the syntactic component list derived in step 1 above (see Syntactic Analysis). Each component contributes to the final total indentation of the line in two ways.
First, the syntactic symbols are looked up in the c-offsets-alist
variable, which is an association list of syntactic symbols and the
offsets to apply for those symbols. These offsets are added to a
running total.
Second, if the component has a relative buffer position, CC Mode adds the column number of that position to the running total. By adding up the offsets and columns for every syntactic component on the list, the final total indentation for the current line is computed.
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 re-indent the line. Remember that the syntactic component list for that line is:
((defun-block-intro . 29))
CC Mode looks up defun-block-intro
in the
c-offsets-alist
variable. Let's say it finds the value `4
';
it adds this to the running total (initialized to zero), yielding a
running total indentation of 4 spaces.
Next CC Mode goes to buffer position 29 and asks for the current
column. This brace is in column zero, so CC Mode
adds `0
' to the running total. Since there is only one syntactic
component 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 component list. Remember that the list for this line is:
((substatement-open . 46))
Here, CC Mode first looks up the substatement-open
symbol
in c-offsets-alist
. Let's say it finds the value `4
'. This
yields a running total of 4. CC Mode then 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 adding this to the
running total yields an indentation for the line of 8 spaces.
Simple, huh?
Actually, 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 component list and calculated offset will always be echoed in
the minibuffer when you hit TAB.