The most flexible way to customize indentation is by writing custom
line-up functions, and associating them with specific syntactic
symbols (see c-offsets-alist). Depending on the effect you want,
it might be better to write a c-special-indent-hook
function
rather than a line-up function (see Other Special Indentations).
CC Mode comes with an extensive set of predefined line-up functions, not all of which are used by the default styles. So there’s a good chance the function you want already exists. See Line-Up Functions, for a list of them. If you write your own line-up function, it’s probably a good idea to start working from one of these predefined functions, which can be found in the file cc-align.el. If you have written a line-up function that you think is generally useful, you’re very welcome to contribute it; please contact bug-cc-mode@gnu.org.
Line-up functions are passed a single argument, the syntactic
element (see below). At the time of the call, point will be somewhere
on the line being indented. The return value is a
c-offsets-alist
offset specification: for example, an integer,
a symbol such as +
, a vector, nil
49, or even another line-up function. Full
details of these are in c-offsets-alist.
Line-up functions must not move point or change the content of the buffer (except temporarily). They are however allowed to do hidden buffer changes, i.e. setting text properties for caching purposes etc. Buffer undo recording is disabled while they run.
The syntactic element passed as the parameter to a line-up function is a cons cell of the form
(syntactic-symbol . anchor-position)
where syntactic-symbol is the symbol that the function was
called for, and anchor-position is the anchor position (if any)
for the construct that triggered the syntactic symbol
(see Syntactic Analysis). This cons cell is how the syntactic
element of a line used to be represented in CC Mode 5.28 and
earlier. Line-up functions are still passed this cons cell, so as to
preserve compatibility with older configurations. In the future, we
may decide to convert to using the full list format—you can prepare
your setup for this by using the access functions
(c-langelem-sym
, etc.) described below.
Some syntactic symbols, e.g. arglist-cont-nonempty
, have more
info in the syntactic element - typically other positions that can be
interesting besides the anchor position. That info can’t be accessed
through the passed argument, which is a cons cell. Instead, you can
get this information from the variable c-syntactic-element
,
which is dynamically bound to the complete syntactic element. The
variable c-syntactic-context
might also be useful - it gets
dynamically bound to the complete syntactic context. See Custom Brace Hanging.
CC Mode provides a few functions to access parts of syntactic
elements in a more abstract way. Besides making the code easier to
read, they also hide the difference between the old cons cell form
used in the line-up function argument and the new list form used in
c-syntactic-element
and everywhere else. The functions are:
Return the syntactic symbol in langelem.
Return the anchor position in langelem, or nil if there is none.
Return the column of the anchor position in langelem. Also move
the point to that position unless preserve-point is
non-nil
.
Return the secondary position in langelem, or nil
if there
is none.
Note that the return value of this function is always nil
if
langelem is in the old cons cell form. Thus this function is
only meaningful when used on syntactic elements taken from
c-syntactic-element
or c-syntactic-context
.
Sometimes you may need to use the syntactic context of a line other
than the one being indented. You can determine this by (temporarily)
moving point onto this line and calling c-guess-basic-syntax
(see Syntactic Analysis).
Custom line-up 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 line-up function associated with it.
Returning
nil
is useful when the offset specification for a syntactic
element is a list containing the line-up function
(see c-offsets-alist).