Lorah Attkins
Lorah Attkins

Reputation: 5856

Is align assignments in clang format broken?

The following is my clang format

---
AccessModifierOffset: '-4'
AlignConsecutiveAssignments: 'true'
AlignOperands: 'true'
AlignTrailingComments: 'true'
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortIfStatementsOnASingleLine: 'true'
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakTemplateDeclarations: 'true'
BinPackArguments: 'true'
BinPackParameters: 'true'
BreakBeforeBraces: Allman
BreakConstructorInitializersBeforeComma: 'true'
ColumnLimit: '80'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
Cpp11BracedListStyle: 'true'
IndentCaseLabels: 'false'
IndentWidth: '4'
MaxEmptyLinesToKeep: '2'
NamespaceIndentation: All
PointerAlignment: Left
SpaceAfterCStyleCast: 'true'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeParens: ControlStatements
SpacesBeforeTrailingComments: '1'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
Standard: Auto
TabWidth: '4'
UseTab: Always

...

But when I run it in a c++ file I get results as the following (the code is gibberish copy-paste, although the problematic area of unaligned assignments is a verbatim copy of what I see as broken in my code)

template <class X>
void prettyPrint(std::ostream& o, const X* x)
{
    o << "*{";
    if (x)
    {
        prettyPrint(o, *x);
    }
    else
    {
        o << "NULL";
    }
    // I wanted the following assignments to align !!!!
    using value_type           = std::decay_t<decltype(state)>;
    using difference_type   = std::ptrdiff_t;
    using reference         = value_type&;
    using pointer             = value_type*;
    using iterator_category = std::input_iterator_tag;

    o << "}";
}

Having set

AlignConsecutiveAssignments: 'true'

I find the above behavior erroneous, is there something in the rest of my .clang-format messing up the result, or should I report this as a bug?

Upvotes: 1

Views: 2962

Answers (2)

anukul
anukul

Reputation: 1962

Using UseTab: Always uses tabs whenever you need to fill whitespace that spans at least from one tab stop to the next one. However, these tabs do not align because the statements preceding them are of varying lengths and print out tabs which go to different tab stops.

A suitable alternative would be to use UseTab: ForIndentation which, as the name suggests, uses tabs only for indentation.

Or even UseTab: Never which never uses tabs.

Upvotes: 4

GeckoGeorge
GeckoGeorge

Reputation: 445

I was able to format the way you want to by deleting the line UseTab: Always in the .clang-format snippet you posted:

template <class X>
void prettyPrint(std::ostream& o, const X* x)
{
    o << "*{";
    if (x)
    {
        prettyPrint(o, *x);
    }
    else
    {
        o << "NULL";
    }
    // I wanted the following assignments to align !!!!
    using value_type        = std::decay_t<decltype(state)>;
    using difference_type   = std::ptrdiff_t;
    using reference         = value_type&;
    using pointer           = value_type*;
    using iterator_category = std::input_iterator_tag;

    o << "}";
}

As to why, I couldn't guess...

Edit: UseTab: ForIndentation or Never also works, only Always breaks it

Upvotes: 1

Related Questions