Next: default mode Up: mode.sc Previous: mode.sc

## C-C++ mode

In C-mode and C++mode the key bindings defined by Smac are:

- tab to reindent the current line. Made by the c_indent_line function.
- return to insert a newline and indents the new line according to previous lines. Made by the c_indent_line function. It may be necessary to type tab after some characters modifying the line context (for instance after case).
- `}', `)' and `]' to insert the character, blink the corresponding `{', `(' and `[', and last reindent the current line. Made by the function named:

  c_insert_blink_matched_char_and_indent.

- `{' and `:' to insert the character and reindent the current line. Made by the function c_indent_line.
- Esc a to go to the beginning of the current or previous definition. The beginning of a definition is supposed to be a line whose first character is not one of `#, }`, space, tab and newline, or whose first two characters are not `//` or `/*`, and whose previous line last char (before newline) is not `\`. Obviously the beginning of the buffer is also considered to be a definition beginning. Made by the function goto_beginning_of_c_definition.
- Esc f goes to the end of the current or next expression (skipping comments). Before a `{,(,[` or `"` it goes after the corresponding `},),]` or `"`, else it goes to the end of the following word. A word contains alphabetic characters, digits and underscore. Made by the forward_c_form function.
- Esc b goes to the beginning of the current or previous expression (skipping comments). Made by the backward_c_form function.
- Esc d deletes the end of the current expression, or the next expression (skipping comments). Made by the delete_next_c_form function.
- Esc delete or Esc backspace deletes the beginning of the current expression or the previous expression (including comments). Made by the function named:

  delete_previous_c_form.

- Esc i indents the current region. If you put a mark at the beginning of the buffer and go to the end before you type Esc i, all the buffer will be reindented (which is not immediate when the buffer is large). Made by the c_indent_region function.

Indentation is parameterized by the following global variables:

- int c_indent_in_comment (default value 3)
- int c_indent_in_string (default value 0)
- int c_indent_in_parenthesis (default value 1)
- int c_indent_in_bracket (default value 1)
- int c_indent_in_brace (default value 2)
- int c_indent_in_statement (default value 2)
- int c_arg_decl_indent (default value 4)

The indentation rules for an empty line, for instance when you type a return at the end of a line, are (take a deep breath):

- In a comment, indentation is set to the previous (not empty or only containing spaces and tabs) line indentation, except for the second line of comments, whose indentation is the ``/*`' position plus the absolute value of c_indent_in_comment. A comment begins with ``/*`' and ends with ``*/`', and a C++ comment with ``//`' and ends at the end of line.
- In a string, if c_indent_in_string is less than 0 the indentation is the string beginning position minus c_indent_in_string (so plus its absolute value), otherwise indentation equals c_indent_in_string.
- In a parenthesis, indentation equals `(' position plus absolute value of the variable c_indent_in_parenthesis.
- In a bracket, indentation equals `[' position plus absolute value of the variable c_indent_in_bracket.
- In a block (between `{}`), all depends on the previous character (skipping space, tab, newline and comments):

  - If it is `{' (so you are at the beginning of the block), indentation is set to the `{' position plus the absolute value of c_indent_in_brace.
  - If it is `}', indentation is set to the indentation of the corresponding `{' or of the expression preceding it.
  - If it is ``.'` or ``;'`, indentation is set to the previous expression indentation.
  - If it is `)' or `]', indentation is set to beginning expression indentation plus the absolute value of c_indent_in_statement.
  - Otherwise the character line indentation plus the absolute value of the variable c_indent_in_statement.

- At top level, all depends on the previous character (skipping space, tab, newline and comments):

  - If it is `}', indentation is set to 0.
  - If it is `)', indentation is set to c_arg_decl_indent because it is probably the parameters of a function written with the old syntax.
  - If it is ``;'`, indentation is set to previous expression indentation.
  - Otherwise, in an expression, indentation is set to the absolute value of c_indent_in_statement, elsewhere 0.

The indentation rules, when you indent a non empty line (for instance when you reindent a line with a tab) depend on the first character(s) (jumping space, tab, newline and comments) (cheer up `!`, we're almost there):

- If it is ``#`', indentation is set to 0.
- If it is ``*`' and the next character is ``/`', so you close a comment, indentation is set to the indentation of the ``/*`'
- If it is a `{' out of a block, indentation is set to 0.
- Otherwise in a block:

  - If it is `}', indentation is set to the indentation of the corresponding `{' or of the expression preceding it.
  - If it is 'case' or 'default', indentation is set to the corresponding switch indentation.
  - If it is ``:'`, indentation is set to the indentation of the corresponding ``?'`.

As you can see, it is rather complicated, nevertheless some cases are not taken into account and need braces. For instance it is the case for nested if like:

are poorly indented:

but the indentation is correct with braces:

Of course the quantity of code interpreted by Smac when you type a simple return is rather disturbing, but don't be afraid, Smac is a good boy.

Next: default mode Up: mode.sc Previous: mode.sc