40

I got the next .clang-format file in my project's root directory:

---
AlignTrailingComments: true
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
BreakBeforeBinaryOperators: false
IndentWidth: 4
SortIncludes: false
NamespaceIndentation: All
...

Problem comes when I run clang-format on my c++ headers, the classes become autoindented like this:

enter image description here

As you can see, labels public & private are indented only with 2 spaces. But what I'm trying to achieve is the below output (indentation was manually tweaked):

enter image description here

That way code-collapsing becomes something really pleasant to do.

How could I tweak my .clang-format to achieve this effect? If not possible, how would you patch clang-format source code to achieve this desired behaviour?

EDIT:

I've tried using unsuccessfully AccessModifierOffset, I've used values {-2,0,2,4} example below:

enter image description here

As you can see the statement inside the public block won't be indented properly.

EDIT2:

I've tried the @Henrique Jung solution and that's definitely not what I'm asking for, if using that combination the result would be something like this one:

enter image description here

And as you can see, the content inside the functions are indented 8 spaces instead 4, which is not good.

EDIT3:

I gave a bounty few months ago so I'm going to try again as this one is definitely interesting. If I got enough knowledge about clang-format source code I'd give it a shot, unfortunately I don't.

halfer
  • 19,824
  • 17
  • 99
  • 186
BPL
  • 9,632
  • 9
  • 59
  • 117
  • try "AccessModifierOffset". This is a possible duplication of another SO question: http://stackoverflow.com/questions/29198963/how-can-i-tell-clang-format-to-indent-visibility-modifiers – caoanan Mar 29 '17 at 03:14
  • 1
    @caoanan Not really, I had already tried AccessModifierOffset few days ago and for some reason it's not indenting properly the classes. While it's true that it will indent public/private/protected it's not indenting the statements below them. Please take a look to my question, I've put you an example – BPL Mar 29 '17 at 09:18
  • Eh, if only I could paste a screenshot [into this](http://clang-format.me/). Seems you like the Webkit style settings. – Hans Passant Oct 28 '17 at 18:58

6 Answers6

9

As near as I can tell, clang-format offers no option for indenting function contents differently from non-access-modifier class contents. That is, consider the following code:

class A {
  public:
    void foo() {}
}

void bar() {
    int a;
}

In this code, the line "void foo() {}" will always be indented the same amount as "int a;" by clang-format.

The closest thing to the style you seem to want that is available would come from not indenting the access modifiers, e.g.:

class A {
public:
    void foo() {}
}

void bar() {
    int a;
}

This is done, for example, by the WebKit, Mozilla, and LLVM styles. It's achieved by setting:

IndentWidth: 4
AccessModifierOffset: -4
Kimby
  • 124
  • 1
  • 4
3

Since you've already set IndentWidth: 4 and based on the image where the indentation was manually tweaked, you need to add these to your .clang-format:

AccessModifierOffset: 0
IndentAccessModifiers: true

Have in mind that clang-format-13 or never is needed to use IndentAccessModifiers option.

Since there is no anchor I can't link it directly, but you should read more about IndentAccessModifiers at https://clang.llvm.org/docs/ClangFormatStyleOptions.html

CleanCoder265
  • 574
  • 1
  • 5
  • 22
  • This worked for me. I created `.clang-format` in the top-level directory of my project, and added `IndentWidth: 4 TabWidth: 4 AccessModifierOffset: 0 IndentAccessModifiers: true` (four settings across four lines, see original question and the parent answer; I cannot add newlines when writing a comment) – miguno Jan 04 '23 at 22:21
1

I managed to achieve the effect you want by changing both AccessModifierOffset with IndentWidth. Basically, the first is used as an offset of the second, so if you create your .clang-format like this you get what you want:

AccessModifierOffset: -4
IndentWidth:     8

If AccessModifierOffset is 0, the public keyword would be at the same level of indentation as the members. However, changing IndentWidth will indent all code by 8 spaces, even those outside the class declaration. This is a sample code:

class Foo {
    public:
        Foo();
        virtual ~Foo(); };

int main(int argc, char *argv[]) {
        std::cout << "Hello world" << std::endl;
        return 0;
}
Henrique Jung
  • 1,408
  • 1
  • 15
  • 23
  • 3
    Thanks for the answer, but that's definitely not what i'm asking for, I've edited my answer to explain why... look the std::cout and return 0 statements, they're indented 8 spaces instead 4, I want 4. – BPL Apr 03 '17 at 18:39
  • Yeah I knew there was a side effect, however I couldn't find an specific indent variable for members. – Henrique Jung Apr 03 '17 at 19:44
1

With clang-format 13 (https://github.com/llvm/llvm-project/releases/tag/llvmorg-13.0.0) you can use:

IndentAccessModifiers: true

to achieve the desired behavior.

If you use default Visual Studio it comes with clang-format 12 which doesn't support this feature. To use it download & install clang-format 13 and from Tools->Options->Text Editor->C/C++->Code Style->Formatting->General check Use custom clang-format.exe file and select clang format 13 executable.

Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211
  • This is the correct answer. The newer version of `clang-format` starting from `13` and up is the solution to the original problem described by the question. – daparic Jan 31 '23 at 01:17
0

I met the same problems, and find the quickest solution is to make a copy of clang default setting(found by Preference -> Package Settings -> Clang Format -> Custom Style-Default) into the user custom setting(Preference -> Package Settings -> Clang Format -> Custom Style - User), then uncomment and modify some options into your own preference. For Example:

"ColumnLimit": 119,
// Indent width for line continuations.
"ContinuationIndentWidth": 4,
// The number of columns to use for indentation.
"IndentWidth": 4,
"TabWidth": 4,
"UseTab": "Never"
ouxiaogu
  • 151
  • 1
  • 11
0

This is just to fomally answer the question. Using the newer clang-format version 13 and up, the configuration should be:

AlignTrailingComments: true
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
BreakBeforeBinaryOperators: false
IndentWidth: 4
IndentAccessModifiers: true
AccessModifierOffset: -4
SortIncludes: false
NamespaceIndentation: All
daparic
  • 3,794
  • 2
  • 36
  • 38