Skip to content

Modified indentation policy for wrapped expressions (with focus on conditions) #4818

Open
@orenbenkiki

Description

@orenbenkiki

📋 Description

This is something I have used in my C code back in the 80s and have been struggling to get code formatters to do ever since (with varying levels of success).

The general rule is: indent the wrapped lines so that operands at the same level in the expression tree have the same indentation; nested operations are "more indented". For best results, when wrapping long lines, parenthesis are always used to clarify the evaluation order and ensure "nested" operations are more indented. This makes a lot of sense for boolean operators anyway (quick, what does a && b || c do?).

For example, in if statements:

if some_condition
&& another_condition
{
    code...
}

if (some_condition
 && another_condition)
|| yet_another_condition
{
    code...
}

if (some_condition
 && another_condition)
|| (yet_another_condition
 && final_condition)
{
    code...
}

This makes the structure of the condition very clear. Compare with the current formatting where the indentation level is actively misleading:

if some_condition
    && another_condition
{
    code... // is indented the same level as the condition, so wasting a line for { is required
}

if (some_condition
    && another_condition)
    || yet_another_condition
{
    // Misleading, another_condition and yet_another_condition have same indentation
}

if (some_condition
    && another_condition)
    || (yet_another_condition
        && final_condition)
{
    // Misleading again; also, symmetric structure of statement is not apparent
}

The proposal generalizes to while statements as follows:

while some_condition
   && (another_condition
    || yet_another_condition)
{
    code...
}

Ideally, I'd love to see this approach be extended to wrapping long expressions in general:

fn foo() -> bool {
    let bar = some_condition
           && another_condition;
       some_condition
    && another_condition
}

And apply this to other operators as well:

fn foo() -> usize {
    let bar = some_value
            + (another_value
             * yet_another_value)
            - final_value;
      some_value
    + (another_value
     * yet_another_value)
    - final_value
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions