GNU Info

Info Node: (ccmode)Custom Indentation Functions

(ccmode)Custom Indentation Functions


Next: Custom Brace and Colon Hanging Up: Advanced Customizations
Enter node , (file) or (file)node

Custom Indentation Functions
----------------------------

   The most flexible way to customize CC Mode is by writing custom
indentation functions, and associating them with specific syntactic
symbols (Note: 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 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))))

Indentation functions take a single argument, which is a syntactic
component cons cell (Note: 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 the column offset
added in twice.

   The function should return `nil' if it's used in a situation where
it doesn't want to do any decision.  If the function is used in a list
expression (Note: 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'(1):

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

   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.  Note: 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>.

   ---------- Footnotes ----------

   (1) It probably makes more sense to add this to `c++-mode-hook' than
`c-mode-common-hook' since stream operators are only relevant for C++.


automatically generated by info2www version 1.2.2.9