clang-format是一个可以格式化代码的工具,本文将介绍如何在命令行中使用clang-format来格式化c++代码,然后会给出一种在c++工程中利用脚本来格式化所有c++文件的工作流程,最后将介绍clang-format中的配置字段,根据自定义的配置字段可以创建自己的代码格式风格。
查看clang-format版本信息的命令:
clang-format --version
输出结果为安装的clang-format版本:
clang-format version 17.0.6
假如有一个需要格式化的文件test.cpp
#include
int main()
{
int a = 0;
int b = 0;
return 0;
}
只需要在test.cpp文件所在的目录打开终端,并输入以下命令:
clang-format -style=llvm -i test.cpp
test.cpp文件即可被格式化为如下:
#include
int main() {
int a = 0;
int b = 0;
return 0;
}
命令行中的-style指定了目标格式的风格,可以选择llvm、google、gnu等格式风格。
另外,我们也可以在test.cpp目录下放置一个.clang-format文件
.
├── .clang-format
└── test.cpp
然后使用命令
clang-format -i test.cpp
即可将test.cpp格式化为目标格式。需要注意的是这种方式不仅对.clang-format文件所在的目录有效,对其子目录的文件也可以格式化。我们可以使用以下命令来快速生成一个.clang-format文件:
clang-format -style=llvm -dump-config > .clang-format
然后可以根据需要修改这个文件形成我们自己的代码格式化风格。
假设有一个c++项目目录结构如下图所示:
.
├── .clang-format
├── Script
│ └── FormatFile.sh
├── Source
│ ├── App
│ │ └── main.cpp
│ ├── LibA
│ │ ├── LibA.cpp
│ │ └── LibA.h
│ └── LibB
│ ├── LibB.cpp
│ └── LibB.h
└── format.sh
其中Source目录包含了cpp源文件,.clang-format文件是自定义的格式风格文件,Script目录包含了项目使用的脚本文件,Script中的FormatFile.sh提供了格式化某个目录下所有文件的接口,实现如下:
function FormatFile()
{
for file in $(ls $1)
do
if [ -d $1"/"$file ]; then
FormatFile $1"/"$file
else
if [[ $1"/"$file = *.h || $1"/"$file = *.cpp ]]; then
clang-format -i $1"/"$file
echo format $1"/"$file
fi
fi
done
}
format.sh脚本通过调用FormatFile.sh中的接口对整个项目中的c++文件进行格式化,每次修改或者提交代码时都可以运行这个脚本,其实现如下:
source ./Script/FormatFile.sh
echo -e "--- start clang-format ---"
FormatFile Source
echo -e "--- finish clang-format ---"
对FormatFile接口传入Source参数,即可将Source目录下的所有c++文件格式化
我们可以通过修改.clang-format文件中的字段来实现自己的代码风格,可参考clang-format的官方文档:
https://clang.llvm.org/docs/ClangFormatStyleOptions.html
本节内容基于clang-format 17
指定编程语言:
Language: Cpp
访问修饰符的缩进(例如public,private等)
AccessModifierOffset: -4
// 修饰符缩进为-4(假设缩进参数为4)
class MyClass {
public:
MyClass();
private:
int m_Num = 0;
};
当需要换行时,控制参数的对齐风格
// AlignAfterOpenBracket: Align
someLooooooooooooongFunction(LoooooooooooooooooooooooooooooooooooooongArgument1,
LoooooooooooooooooooooooooooooooooooooongArgument2,
Argument3);
// AlignAfterOpenBracket: DontAlign
someLooooooooooooongFunction(LoooooooooooooooooooooooooooooooooooooongArgument1,
LoooooooooooooooooooooooooooooooooooooongArgument2, Argument3);
// AlignAfterOpenBracket: AlwaysBreak
someLooooooooooooongFunction(
LoooooooooooooooooooooooooooooooooooooongArgument1,
LoooooooooooooooooooooooooooooooooooooongArgument2, Argument3);
// AlignAfterOpenBracket: BlockIndent
someLooooooooooooongFunction(
LoooooooooooooooooooooooooooooooooooooongArgument1,
LoooooooooooooooooooooooooooooooooooooongArgument2, Argument3
);
对结构数组初始化时,字段排列成列的方式
// None
AlignArrayOfStructures: None
int Nums[4][3] = {
{56, 23, 1557}, {-1, 93463, 422}, {7, 5, 10}, {7801, 15, 8010}};
// 按左对齐
AlignArrayOfStructures: Left
int Nums[4][3] = {
{56, 23, 1557},
{-1, 93463, 422 },
{7, 5, 10 },
{7801, 15, 8010}
};
// 按右对齐
AlignArrayOfStructures: Right
int Nums[4][3] = {
{ 56, 23, 1557},
{ -1, 93463, 422},
{ 7, 5, 10},
{7801, 15, 8010}
};
连续赋值语句的对齐方式,有Enabled、AcrossEmptyLines、AcrossComments、AlignCompound、PadOperators五个选项,分别可以有true和false两个值
Enabled: 是否开启对齐
// Enabled: false
int a = 0;
int bbbbb = 1;
int cc = 5;
// Enabled: true
int a = 0;
int bbbbb = 1;
int cc = 5;
AcrossEmptyLines: 是否跨空行对齐
// AcrossEmptyLines: false
int a = 0;
int bbbbb = 1;
int cc = 5;
int somelongname = 2;
double c = 3;
// AcrossEmptyLines: true
int a = 0;
int bbbbb = 1;
int cc = 5;
int somelongname = 2;
double c = 3;
AcrossComments: 是否跨注释对齐
// AcrossComments: false
int a = 3;
int bbb = 10;
/* comment. */
double e = 4;
float fffff = 4;
// AcrossComments: true
int a = 3;
int bbb = 10;
/* comment. */
double e = 4;
float fffff = 4;
AlignCompound: 复合赋值是否和等号赋值一起对齐
// AlignCompound: false
aaaaaa &= 2;
bb = 2;
// AlignCompound: true
aaaaaa &= 2;
bb = 2;
PadOperators: 短赋值运算符号是否左填充到和长赋值运算符相同的长度
// AlignCompound需要为true
// PadOperators: false
a >>= 2;
bbb = 2;
a = 2;
bbb >>= 2;
// PadOperators: true
a >>= 2;
bbb = 2;
a = 2;
bbb >>= 2;
连续位字段的对齐方式
// Enabled: false
struct MyStruct {
int aaaa : 1;
int b : 12;
int ccc : 8;
};
// Enabled: true
struct MyStruct {
int aaaa : 1;
int b : 12;
int ccc : 8;
};
连续的声明语句的对齐方式
// AlignConsecutiveDeclarations: false
int aaaa = 12;
float b = 23;
std::string ccc;
// AlignConsecutiveDeclarations: true
int aaaa = 12;
float b = 23;
std::string ccc;
连续的宏定义的对齐方式
// AlignConsecutiveMacros: false
#define SHORT_NAME 42
#define LONGER_NAME 0x007f
#define EVEN_LONGER_NAME (2)
#define foo(x) (x * x)
#define bar(y, z) (y + z)
// AlignConsecutiveMacros: true
#define SHORT_NAME 42
#define LONGER_NAME 0x007f
#define EVEN_LONGER_NAME (2)
#define foo(x) (x * x)
#define bar(y, z) (y + z)
用于控制连续的case语句的对齐方式,需要设置AllowShortCaseLabelsOnASingleLine为true
Enabled
// Enabled: false
switch (level)
{
case log::info: return "info:";
case log::warning: return "warning:";
default: return "";
}
// Enabled: true
switch (level)
{
case log::info: return "info:";
case log::warning: return "warning:";
default: return "";
}
AcrossEmptyLines
// AcrossEmptyLines: false
switch (level)
{
case 123: return 123;
case 12'344'444: return 12'344'444;
case 234: return 234;
default: return 234;
}
// AcrossEmptyLines: true
switch (level)
{
case 123: return 123;
case 12'344'444: return 12'344'444;
case 234: return 234;
default: return 234;
}
AcrossComments
// AcrossComments: false
switch (level)
{
case 123: return 123;
case 12'344'444: return 12'344'444;
// A comment
case 234: return 234;
default: return 234;
}
// AcrossComments: true
switch (level)
{
case 123: return 123;
case 12'344'444: return 12'344'444;
// A comment
case 234: return 234;
default: return 234;
}
AlignCaseColons
// AlignCaseColons: false
switch (level)
{
case 123: return 123;
case 12'344'444: return 12'344'444;
case 234: return 234;
default: return 234;
}
// AlignCaseColons: true
switch (level)
{
case 123 : return 123;
case 12'344'444: return 12'344'444;
case 234 : return 234;
default : return 234;
}
转义换行符的对齐方式
// AlignEscapedNewlines: DontAlign
#define A \
int aaaa; \
int b; \
int dddddddddd;
// AlignEscapedNewlines: Left
#define A \
int aaaa; \
int b; \
int dddddddddd;
// AlignEscapedNewlines: Right
#define A \
int aaaa; \
int b; \
int dddddddddd;
换行时,二元和三元操作符的对齐方式
// BreakBeforeBinaryOperators设置为All
// AlignOperands: DontAlign
int aaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ ccccccccccccccccccccccccccccccccccccccccc;
// AlignOperands: Align
int aaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ ccccccccccccccccccccccccccccccccccccccccc;
// AlignOperands: AlignAfterOperator
int aaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ ccccccccccccccccccccccccccccccccccccccccc;
控制尾部注释的对齐方式,有Kind和OverEmptyLines两个选项,Kind控制对齐的方式,OverEmptyLines控制对齐的空行数
// Kind: Leave
int a; // comment
int abbbbbb; // comment
// Kind: Always
int a; // comment
int abbbbbb; // comment
// Kind: Never
int a; // comment
int abbbbbb; // comment
函数调用需要换行时,是否允许把所有的参数放到下一行
// BinPackArguments设置为false
// AllowAllArgumentsOnNextLine: false
void func()
{
dosomething();
funccccccccccccccccccccc(
LoooooooooooooooooooooooogArg1,
LongArg2,
LongArg2
);
}
// AllowAllArgumentsOnNextLine: true
void func()
{
dosomething();
funccccccccccccccccccccc(
LoooooooooooooooooooooooogArg1, LongArg2, LongArg2
);
}
是否允许把所有的参数声明放到下一行
是否允许短块在一行中
// AllowShortBlocksOnASingleLine设置为Always
// AllowShortBlocksOnASingleLine: Never
while (true)
{
}
while (true)
{
continue;
}
// AllowShortBlocksOnASingleLine: Empty
while (true)
{
}
while (true)
{
continue;
}
// AllowShortBlocksOnASingleLine: Always
while (true) { }
while (true) { continue; }
是否允许短的case标签在一行中
// AllowShortCaseLabelsOnASingleLine: false
switch (a) {
case 1:
x = 1;
break;
case 2:
x = 5;
break;
default:
break;
}
// AllowShortCaseLabelsOnASingleLine: true
switch (a) {
case 1: x = 1; break;
case 2: x = 5; break;
default: break;
}
是否允许短的枚举类型在一行中
// AllowShortEnumsOnASingleLine: false
enum class Color {
Red,
Green,
Blue
};
// AllowShortEnumsOnASingleLine: true
enum class Color { Red, Green, Blue };
是否允许短函数在一行中
// AllowShortFunctionsOnASingleLine: None
// 不允许单行
class Foo {
void Func1() {
foo();
}
void Func2() {
}
};
void Func3() {
foo();
}
void Func4() {
}
// AllowShortFunctionsOnASingleLine: InlineOnly
// 只有类里面的短函数单行
class Foo {
void Func1() { foo(); }
void Func2() {}
};
void Func3() {
foo();
}
void Func4() {
}
// AllowShortFunctionsOnASingleLine: Inline
// 只有类里面的短函数以及空函数单行
class Foo {
void Func1() { foo(); }
void Func2() {}
};
void Func3() {
foo();
}
void Func4() {}
// AllowShortFunctionsOnASingleLine: All
// 所有短函数单行
class Foo {
void Func1() { foo(); }
void Func2() {}
};
void Func3() { foo(); }
void Func4() {}
是否允许短的if语句在一行中
// AllowShortIfStatementsOnASingleLine: Never
if (a)
return;
// AllowShortIfStatementsOnASingleLine: WithoutElse
if (a) return;
if (a)
return;
else
return;
// AllowShortIfStatementsOnASingleLine: OnlyFirstIf
if (a) return;
if (a == 1) return;
else if (a == 2)
return;
else
return;
// AllowShortIfStatementsOnASingleLine: AllIfsAndElse
if (a) return;
if (a == 1) return;
else if (a == 2) return;
else return;
是否允许短的lambda函数在一行
// AllowShortLambdasOnASingleLine: None
auto lambda = [](int x, int y) {
};
auto lambda2 = [](int x, int y) {
return x < y;
};
std::sort(a.begin(), a.end(), [](int x, int y) {
return x < y;
});
// AllowShortLambdasOnASingleLine: Empty
auto lambda = [](int x, int y) {};
auto lambda2 = [](int x, int y) {
return x < y;
};
std::sort(a.begin(), a.end(), [](int x, int y) {
return x < y;
});
// AllowShortLambdasOnASingleLine: Inline
auto lambda = [](int x, int y) {
};
auto lambda2 = [](int x, int y) {
return x < y;
};
std::sort(a.begin(), a.end(), [](int x, int y) { return x < y; });
// AllowShortLambdasOnASingleLine: All
auto lambda = [](int x, int y) {};
auto lambda2 = [](int x, int y) { return x < y; };
std::sort(a.begin(), a.end(), [](int x, int y) { return x < y; });
// AllowShortLoopsOnASingleLine: false
for (int i = 0; i < 10; ++i) {
doSomething(i);
}
while (true) {
doSomething(i);
}
// AllowShortLoopsOnASingleLine: true
for (int i = 0; i < 10; ++i) { doSomething(i); }
while (true) { doSomething(i); }
废弃的字段
函数声明返回的换行方式
// AlwaysBreakAfterReturnType: None
class A
{
int f() { return 0; };
};
int f();
int f() { return 1; }
// AlwaysBreakAfterReturnType: All
class A
{
int
f()
{
return 0;
};
};
int
f();
int
f()
{
return 1;
}
// AlwaysBreakAfterReturnType: TopLevel
class A
{
int f() { return 0; };
};
int
f();
int
f()
{
return 1;
}
// AlwaysBreakAfterReturnType: AllDefinitions
class A
{
int
f()
{
return 0;
};
};
int f();
int
f()
{
return 1;
}
// AlwaysBreakAfterReturnType: TopLevelDefinitions
class A
{
int f() { return 0; };
};
int f();
int
f()
{
return 1;
}
决定多行字符前是否换行
// AlwaysBreakBeforeMultilineStrings: false
aaaa = "bbbb"
"cccc";
// AlwaysBreakBeforeMultilineStrings: true
aaaa =
"bbbb"
"cccc";
模版声明的换行方式
// AlwaysBreakTemplateDeclarations: No
template T foo() { }
template T foo(
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
)
{
}
// AlwaysBreakTemplateDeclarations: MultiLine
template
T foo(
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
)
{
}
// AlwaysBreakTemplateDeclarations: Yes
template
T foo()
{
}
template
T foo(
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
)
{
}
设置的字符串被解释为属性/限定符,而不是标识符
在函数调用时,设置为false时,如果参数需要换行,那么每个参数都换行
// BinPackArguments: false
void func()
{
funccccccccccccccccccccc(
LoooooooooooooooooooooooooooooooooooonoooooooooooooogArg1,
LongArg2,
LongArg2
);
}
// BinPackArguments: true
void func()
{
funccccccccccccccccccccc(
LoooooooooooooooooooooooooooooooooooonoooooooooooooogArg1, LongArg2,
LongArg2
);
}
在函数声明/定义时,设置为false时,如果参数需要换行,那么每个参数都换行
// BinPackParameters: false
void f(
int aaaaaaaaaaaaaaaaaaaa1,
int aaaaaaaaaaaaaaaaaaaa2,
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3
)
{
}
// BinPackParameters: true
void f(
int aaaaaaaaaaaaaaaaaaaa1, int aaaaaaaaaaaaaaaaaaaa2,
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3
)
{
}
控制位域操作符两边是否有空格
// BitFieldColonSpacing: Both
struct MyStruct {
int a : 8;
char b : 10;
}
// BitFieldColonSpacing: None
struct MyStruct {
int a:8;
char b:10;
}
// BitFieldColonSpacing: Before
struct MyStruct {
int a :8;
char b :10;
}
// BitFieldColonSpacing: After
struct MyStruct {
int a: 8;
char b: 10;
}
用于控制大括号的换行,想要BraceWrapping生效需要设置BreakBeforeBraces为Custom
AfterCaseLabel: case标签的大括号
// AfterCaseLabel: false
switch (a) {
case 1: {
dosomething();
break;
}
case 1: {
dosomething();
break;
}
default: {
break;
}
}
// AfterCaseLabel: true
switch (a) {
case 1:
{
dosomething();
break;
}
case 1:
{
dosomething();
break;
}
default:
{
break;
}
}
AfterClass: 类定义的大括号
// AfterClass: false
class MyClass {
public:
MyClass();
}
// AfterClass: true
class MyClass
{
public:
MyClass();
}
AfterControlStatement: 控制语句(if/for/while/switch/..)的大括号
// AfterControlStatement: Never
if (a && b) {
}
if (aaaaaaaaaaaaaaaaaaaa &&
bbbbbbbbbbbbbbbbbbbbbbbbbbbbb & ccccccccccccccccccccc) {
}
// AfterControlStatement: MultiLine
if (a && b) {
}
if (aaaaaaaaaaaaaaaaaaaa &&
bbbbbbbbbbbbbbbbbbbbbbbbbbbbb & ccccccccccccccccccccc)
{
}
// AfterControlStatement: Always
if (a && b)
{
}
if (aaaaaaaaaaaaaaaaaaaa &&
bbbbbbbbbbbbbbbbbbbbbbbbbbbbb & ccccccccccccccccccccc)
{
}
AfterEnum: enum定义的大括号
// AfterEnum: false
enum class Color {
Red,
Green,
Blue
};
// AfterEnum: true
enum class Color
{
Red,
Green,
Blue
};
AfterExternBlock: extern代码块的大括号
// AfterExternBlock: false
extern "C" {
int foo();
}
// AfterExternBlock: true
extern "C"
{
int foo();
}
AfterFunction: 函数定义的大括号
// AfterFunction: false
void foo() {
dosomething();
dosomething();
}
// AfterFunction: true
void foo()
{
dosomething();
dosomething();
}
AfterNamespace: namespace定义的大括号
// AfterNamespace: false
namespace MyNamespace {
void Foo1();
void Foo2();
} // namespace MyNamespace
// AfterNamespace: true
namespace MyNamespace
{
void Foo1();
void Foo2();
} // namespace MyNamespace
AfterObjCDeclaration: 控制Objective-C声明后的代码格式
AfterStruct: struct定义的大括号
// AfterStruct: false
struct MyStruct {
int a;
int b;
}
// AfterStruct: true
struct MyStruct
{
int a;
int b;
}
AfterUnion: union定义的大括号
// AfterUnion: false
union MyUnion {
int a;
double b;
}
// AfterUnion: true
union MyUnion
{
int a;
double b;
}
BeforeCatch: catch前的大括号
// BeforeCatch: false
try {
foo();
} catch {
dosomething();
}
// BeforeCatch: true
try {
foo();
}
catch {
dosomething();
}
BeforeElse: else之前的大括号
// BeforeElse: false
if (a) {
foo1();
} else {
foo2();
}
// BeforeElse: true
if (a) {
foo1();
}
else {
foo2();
}
BeforeLambdaBody: lambda函数的大括号
// BeforeLambdaBody: false
auto lambda2 = [](int x, int y) {
dosomething();
dosomething();
};
// BeforeLambdaBody: true
auto lambda2 = [](int x, int y)
{
dosomething();
dosomething();
};
BeforeWhile: while前的大括号
// BeforeWhile: false
do {
foo();
} while (1);
// BeforeWhile: true
do {
foo();
}
while (1);
IndentBraces:
不知道有什么用
SplitEmptyFunction: 决定空函数的大括号是否放在一行
// AfterFunction设置为true
// SplitEmptyFunction: false
void Func()
{}
// SplitEmptyFunction: true
void Func()
{
}
SplitEmptyRecord: 控制空的class/stuct/union的大括号是否放在一行
// AfterStruct设置为true
// SplitEmptyRecord: false
struct MyStruct
{}
// SplitEmptyRecord: true
struct MyStruct
{
}
SplitEmptyNamespace: 空namespace的大括号是否放在一行
// AfterNamespace设置为true
// SplitEmptyNamespace: false
namespace MyNamespace
{}
// SplitEmptyNamespace: true
namespace MyNamespace
{
}
是否在属性声明后换行
// BreakAfterAttributes: Never
void Func()
{
[[maybe_unused]] const int i;
[[gnu::const]] [[maybe_unused]] int j;
[[likely]] if (a)
f();
else
g();
}
[[nodiscard]] inline int f();
[[gnu::const]] [[nodiscard]] int g();
// BreakAfterAttributes: Always
void Func()
{
[[maybe_unused]] const int i;
[[gnu::const]] [[maybe_unused]] int j;
[[likely]] if (a)
f();
else
g();
}
[[nodiscard]]
inline int f();
[[gnu::const]] [[nodiscard]]
int g();
// BreakAfterAttributes: Leave 保持原样
是否在Java字段注解之后换行
用于决定Json文件中的数组是否换行
用于控制当需要换行时,二元操作符的换行方式
// BreakBeforeBinaryOperators: None
// 在操作符后换行
LooooooooooongType loooooooooooooooooooooongVariable =
someLooooooooooooooooongFunction();
bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >
ccccccccccccccccccccccccccccccccccccccccc;
// BreakBeforeBinaryOperators: NonAssignment
// 对于非赋值符号,在操作符前换行
LooooooooooongType loooooooooooooooooooooongVariable =
someLooooooooooooooooongFunction();
bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
== aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
&& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
> ccccccccccccccccccccccccccccccccccccccccc;
// BreakBeforeBinaryOperators: All
// 在操作符前换行
LooooooooooongType loooooooooooooooooooooongVariable
= someLooooooooooooooooongFunction();
bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
== aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
&& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
> ccccccccccccccccccccccccccccccccccccccccc;
concept声明的换行格式
// BreakBeforeConceptDeclarations: Never
template concept C = ...;
// BreakBeforeConceptDeclarations: Always
template
concept C = ...;
// BreakBeforeConceptDeclarations: Allowed
// 允许concept声明换行,具体和代码内容相关
大括号的换行方式,如果定义为Custom,则使用BraceWrapping来自定义大括号的换行方式,其他的值有
Attach: 大括号始终和周围的上下文保持一行
Allman: 大括号始终换行
以及Linux、Mozilla、Stroustrup、Whitesmiths、GNU、WebKit等可选值
用于控制是否在汇编代码中的冒号前换行
控制三元运算符的换行
// BreakBeforeTernaryOperators: false
veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription ?
firstValue :
SecondValueVeryVeryVeryVeryLong;
// BreakBeforeTernaryOperators: true
veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription
? firstValue
: SecondValueVeryVeryVeryVeryLong;
控制构造函数初始化列表这么换行
// 设置PackConstructorInitializers为Never
// BreakConstructorInitializers: BeforeColon
struct MyClass
{
MyClass()
: m_a(0),
m_b(0)
{
}
int m_a;
int m_b;
};
// BreakConstructorInitializers: BeforeComma
struct MyClass
{
MyClass()
: m_a(0)
, m_b(0)
{
}
int m_a;
int m_b;
};
// BreakConstructorInitializers: AfterColon
struct MyClass
{
MyClass():
m_a(0),
m_b(0)
{
}
int m_a;
int m_b;
};
设置继承列表的换行风格
// BreakInheritanceList: BeforeColon
class Foo : Base1, Base2, Base3
{
};
// BreakInheritanceList: BeforeComma
class Foo
: Base1
, Base2
, Base3
{
};
// BreakInheritanceList: AfterColon
class Foo : Base1, Base2, Base3
{
};
// BreakInheritanceList: AfterComma
class Foo : Base1,
Base2,
Base3
{
};
当代码列数超过限制时,是否允许字符串字面量换行
// origin code
const char *x
= "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
// BreakStringLiterals: false
const char *x
= "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
// BreakStringLiterals: true
const char *x
= "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong"
"String";
设置代码的最大列数,如果设置为0则没有限制
用于控制注释的格式,符合正则表达式的注释保持在同一行
// CommentPragmas: 'TODO'
void Func()
{
int a
= 0; // TODO : a very loooooooooooooooooooooooooooooooooooooooooooooog
}
// CommentPragmas: 'Other'
void Func()
{
int a = 0; // TODO : a very
// loooooooooooooooooooooooooooooooooooooooooooooog
}
是否将连续的namespace放在一行
// CompactNamespaces: false
namespace Foo {
namespace Bar { }
} // namespace Foo
// CompactNamespaces: true
namespace Foo { namespace Bar {
}} // namespace Foo::Bar
构造函数初始化列表以及的继承列表的缩进宽度
// ConstructorInitializerIndentWidth: 4
struct MyClass
{
MyClass():
m_a(0),
m_b(0),
m_c(0)
};
struct MyClass
: Base1
, Base2
{
};
// ConstructorInitializerIndentWidth: 10
struct MyClass
{
MyClass():
m_a(0),
m_b(0),
m_c(0)
};
struct MyClass
: Base1
, Base2
{
};
连续行的缩进宽度
// ContinuationIndentWidth: 4
int i = // VeryVeryVeryVeryVeryLongComment
longFunction( // Again a long comment
arg1, // Again a long comment
arg2);
设置包围列表的格式
// Cpp11BracedListStyle: false
std::vector x{ 1, 2, 3, 4 };
std::vector x{ {}, {}, {}, {} };
f(MyMap[{ composite, key }]);
new int[3]{ 1, 2, 3 };
// Cpp11BracedListStyle: true
std::vector x{1, 2, 3, 4};
std::vector x{{}, {}, {}, {}};
f(MyMap[{composite, key}]);
new int[3]{1, 2, 3};
是否自动推断指针的对齐方式
完全禁止格式化
是否在访问修饰符后放置空行
// EmptyLineAfterAccessModifier: Never
struct foo {
private:
int i;
protected:
int j;
/* comment */
public:
foo() {
}
private:
protected:
};
// EmptyLineAfterAccessModifier: Leave
// 保持原样
// EmptyLineAfterAccessModifier: Always
struct foo {
private:
int i;
protected:
int j;
/* comment */
public:
foo() {
}
private:
protected:
};
是否在访问修饰符前放置空行
// EmptyLineAfterAccessModifier: Leave 保持原状
// EmptyLineAfterAccessModifier: Never
struct foo
{
private:
int i;
protected:
int j;
/* comment */
public:
foo() { }
private:
protected:
};
// EmptyLineAfterAccessModifier: Always
struct foo
{
private:
int i;
protected:
int j;
/* comment */
public:
foo() { }
private:
protected:
};
自动检测和调整二进制。这是一个试验性字段,尽量不要使用
自动修复命名空间注释的格式问题
// FixNamespaceComments: false
namespace longNamespace {
void foo();
void bar();
}
namespace shortNamespace {
void baz();
}
// FixNamespaceComments: true
namespace longNamespace {
void foo();
void bar();
} // namespace longNamespace
namespace shortNamespace {
void baz();
}
定义的宏应该被解释为foreach循环,而不是函数调用
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
定义的宏应该被解释为条件语句,而不是函数调用
IfMacros:
- KJ_IF_MAYBE
对头文件块进行划分,然后根据IncludeCategories策略对头文件进行排序
// IncludeBlocks: Preserve
// 每个头文件各自排序
#include "a.h"
#include "b.h"
#include
// IncludeBlocks: Merge
// 所有的头文件块合成一组后排序
#include "a.h"
#include "b.h"
#include
// IncludeBlocks: Regroup
// 所有的头文件块合成一组排序,然后根据种类分成不同的块
#include "a.h"
#include "b.h"
#include
定义不同类型的头文件的优先级用于排序
IncludeCategories:
- Regex: '^'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
Regex用于匹配头文件
Priority定义头文件的优先级,用于排序
SortPriority用于当IncludeBlocks设置为Regroup时,头文件所在组的优先级,如果SortPriority没有赋值,默认和Priority的值相同
CaseSensitive定义是否区分大小写
用于匹配非标准扩展名的文件,这些文件可以被视为主包含文件
用于匹配非标准扩展名的文件,这些文件可以被视为主源文件
控制访问修饰符的缩进,如果为false,那么就根据后面的成员以及AccessModifierOffset的值进行缩进,如果为true,那么会将访问修饰符进行单独的缩进
// IndentAccessModifiers: false
class MyClass {
public:
void foo();
public:
int m_b;
};
// IndentAccessModifiers: true
class MyClass {
public:
void foo();
public:
int m_b;
};
case标签后面的大括号是否缩进
// IndentCaseBlocks: false
switch (variable)
{
case 1:
{
dosomething();
break;
}
case 2:
{
dosomething();
break;
}
default:
{
dosomething();
break;
}
}
// IndentCaseBlocks: true
switch (variable)
{
case 1:
{
dosomething();
break;
}
case 2:
{
dosomething();
break;
}
default:
{
dosomething();
break;
}
}
case标签是否缩进
// IndentCaseLabels: false
switch (variable)
{
case 1:
dosomething();
break;
case 2:
dosomething();
break;
default:
dosomething();
break;
}
// IndentCaseLabels: true
switch (variable)
{
case 1:
dosomething();
break;
case 2:
dosomething();
break;
default:
dosomething();
break;
}
控制extern代码块的缩进
// BreakBeforeBraces: Custom
// BraceWrapping.AfterExternBlock: true
// IndentExternBlock: AfterExternBlock
extern "C"
{
void foo();
}
// BreakBeforeBraces: Custom
// BraceWrapping.AfterExternBlock: false
// IndentExternBlock: AfterExternBlock
extern "C" {
void foo();
}
// IndentExternBlock: NoIndent
extern "C"
{
void foo();
}
// IndentExternBlock: Indent
extern "C"
{
void foo();
}
当IndentGotoLabels为false时,goto的标签会靠左放置
// IndentGotoLabels: false
int foo()
{
if (foo())
{
label1:
bar();
}
label2:
return 1;
}
// IndentGotoLabels: true
int foo()
{
if (foo())
{
label1:
bar();
}
label2:
return 1;
}
控制与处理器的缩进格式
// IndentPPDirectives: None
#if FOO
#if BAR
#include
#endif
#endif
// IndentPPDirectives: AfterHash
#if FOO
# if BAR
# include
# endif
#endif
// IndentPPDirectives: BeforeHash
#if FOO
#if BAR
#include
#endif
#endif
是否缩进模版中的requires子句,需要设置RequiresClausePosition为OwnLine或者WithFollowing
// IndentRequiresClause: false
template
requires Iterator
void sort(It begin, It end)
{
//....
}
// IndentRequiresClause: true
template
requires Iterator
void sort(It begin, It end)
{
//....
}
缩进宽度
是否缩进函数名
// IndentWrappedFunctionNames: false
LoooooooooooooooooooooooooooooooooooooooongReturnType
LoooooooooooooooooooooooooooooooongFunctionDeclaration(int a, int b);
// IndentWrappedFunctionNames: true
LoooooooooooooooooooooooooooooooooooooooongReturnType
LoooooooooooooooooooooooooooooooongFunctionDeclaration(int a, int b);
是否添加大括号。谨慎使用,可能会生成错误的代码
// InsertBraces: false
if (1)
foo1();
else if (2)
foo2();
else
foo3();
// InsertBraces: true
if (1)
{
foo1();
}
else if (2)
{
foo2();
}
else
{
foo3();
}
是否在文件末尾添加一个空行
对整数文本添加分隔符,值为0表示保持文本原样,值为负数表示去掉所有的分隔符,值为正数表示分隔符的间隔数
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 3
DecimalMinDigits: 5
Hex: -1
HexMinDigits: 0
DecimalMinDigits表示十进制数至少是5位数才添加分隔符
a = 0b10011'11'0110'1;
b = 4592;
c = 18'446'744'073'709'550'592;
d = 0xDEADBEEFDEADBEEFuz;
是否保留代码块第一行的空行
// KeepEmptyLinesAtTheStartOfBlocks: true
if (0)
{
dosomething();
}
// KeepEmptyLinesAtTheStartOfBlocks: false
if (0)
{
dosomething();
}
是否保留文件结尾的空行
lambda函数体的缩进方式
// LambdaBodyIndentation: Signature
someMethod(
[](int a)
{
dosomething();
return;
});
// LambdaBodyIndentation: OuterScope
someMethod(
[](int a)
{
dosomething();
return;
});
代码行的结束方式,可以选择LE_LF、LE_CRLF、LE_DeriveLF、LE_DeriveCRLF等
MacroBlockBegin和MacroBlockEnd之间的代码会被缩进,MacroBlockBegin和MacroBlockEnd是正则表达式
// MacroBlockBegin: 'M_BEGIN'
// MacroBlockEnd: 'M_END'
M_BEGIN
int a = 0;
double b = 0;
M_END
设置最大的连续空行
// MaxEmptyLinesToKeep: 3
int func()
{
int a = 1;
int b = 1;
int c = 1;
return 0;
}
// MaxEmptyLinesToKeep: 1
int func()
{
int a = 1;
int b = 1;
int c = 1;
return 0;
}
命名空间的缩进方式
// NamespaceIndentation: None
namespace out
{
int i;
namespace in
{
int i;
}
} // namespace out
// NamespaceIndentation: Inner
namespace out
{
int i;
namespace in
{
int i;
}
} // namespace out
// NamespaceIndentation: All
namespace out
{
int i;
namespace in
{
int i;
}
} // namespace out
构造函数初始化使用的格式
// PackConstructorInitializers: Never
// 总是每个初始化单独放一行
struct MyClass
{
MyClass():
m_a(0),
m_b(0),
m_c(0)
{
}
};
// PackConstructorInitializers: BinPack
// 尝试将构造函数初始化列表紧密地放在一行上,以减少行数
struct MyClass
{
MyClass():
aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(), cccccccccccccccccccc()
{
}
};
// PackConstructorInitializers: CurrentLine
// 如果可以放在一行就全部放在一行,否则就每个初始化各一行
struct MyClass
{
MyClass(): aaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbb(), ccccccccccccccccc() { }
};
struct MyClass
{
MyClass():
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(),
bbbbbbbbb(),
ccccc()
{
}
};
// PackConstructorInitializers: NextLine
// 和CurrentLine相同,不过如果当前行放不下,尽量放在下一行,否则就单独一行
struct MyClass
{
MyClass(): aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(), ddddddddddddd()
{
}
};
struct MyClass
{
MyClass():
aaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbb(), cccccccccccccccccccccc()
{
}
};
struct MyClass
{
MyClass():
aaaaaaaaaaaaaaaaa(),
bbbbbbbbbbbbbbbbb(),
ccccccccccccccccccccccccccccccc()
{
}
};
// PackConstructorInitializers: NextLineOnly
// 如果下一行放不下,就单独放一行
struct MyClass
{
MyClass():
aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(), ddddddddddddd()
{
}
};
struct MyClass
{
MyClass():
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(),
bbbbbbbbbbbbbbbbbbbb(),
ddddddddddddd()
{
}
};
指针和引用的对齐风格
// 设置DerivePointerAlignment为false
// PointerAlignment: Left
int* a = nullptr;
int& b = *a;
int*& c = a;
// PointerAlignment: Right
int *a = nullptr;
int &b = *a;
int *&c = a;
// PointerAlignment: Middle
int * a = nullptr;
int & b = *a;
int *& c = a;
预处理器的缩进宽度,为-1时和IndentWidth保持一致
// PPIndentWidth: -1
#ifdef __linux__
#define FOO
#else
#define BAR
#endif
// PPIndentWidth: 10
#ifdef __linux__
#define FOO
#else
#define BAR
#endif
说明符和限定符的排列方式,最好设置为Leave,否则可能生成错误的代码
// QualifierAlignment: Leave
int const a;
const int* a;
// QualifierAlignment: Left
const int a;
const int* a;
// QualifierAlignment: Right
int const a;
int const* a;
// QualifierAlignment: Custom
// 使用QualifierOrder的定义
设置原始字符串的格式与特定语言的风格指南保持一致
// 设置原始字符串的格式与为基于google的c++风格
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
引用的对齐方式,值为Pointer时,和指针的对齐方式相同,还可以设置为Left,Right,Middle
注释过长时,是否重新排列注释
// ReflowComments: false
// veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
/* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */
// ReflowComments: true
// veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
// information
/* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
* information */
根据llvm的风格决定是否去掉不必要的大括号,最好设置为false,否则可能会生成错误的代码
删除多余的括号,最好设置为Leave,否则可能会生成错误的代码
删除非空函数的右大括号后面的分号,最好设置为false,否则可能会生成错误的代码
设置requires子句的位置
// RequiresClausePosition: OwnLine
template
requires C
struct Foo
{
};
template
requires C
void bar(T t)
{
}
template
void baz(T t)
requires C
{
}
// RequiresClausePosition: WithPreceding
template
requires C
struct Foo
{
};
template
requires C
void bar(T t)
{
}
template
void baz(T t) requires C
{
}
// RequiresClausePosition: WithFollowing
template
requires C struct Foo
{
};
template
requires C void bar(T t)
{
}
template
void baz(T t)
requires C
{
}
// RequiresClausePosition: SingleLine
template
requires C struct Foo
{
};
template
requires C void bar(T t)
{
}
template
void baz(T t) requires C
{
}
用于控制require表达式的缩进
// RequiresExpressionIndentation: OuterScope
template
concept C = requires(T t) {
...;
...;
}
// RequiresExpressionIndentation: Keyword
template
concept C = requires(T t) {
...;
...;
}
是否使用空行分隔定义块,包括class、struct、enum、函数等
// SeparateDefinitionBlocks: Leave
#include
class MyClass
{
};
struct MyStruct
{
};
enum class MyEnum
{
};
void Func() {}
void Func2() {}
// SeparateDefinitionBlocks: Always
#include
class MyClass
{
};
struct MyStruct
{
};
enum class MyEnum
{
};
void Func() {}
void Func2() {}
// SeparateDefinitionBlocks: Never
#include
class MyClass
{
};
struct MyStruct
{
};
enum class MyEnum
{
};
void Func() {}
void Func2() {}
当命令空间中的代码行数小于设定的值时,这类命令空间称为短命名空间。短命名空间可以不受FixNamespaceComments字段的影响
// FixNamespaceComments: true
// ShortNamespaceLines: 2
namespace A
{
int a;
int b;
int c;
} // namespace A
namespace B
{
int a;
}
// ShortNamespaceLines: 0
namespace A
{
int a;
int b;
int c;
} // namespace A
namespace B
{
int a;
} // namespace B
控制排序头文件的方式,最高设置为Never,c++中的头文件顺序可能对代码有影响
// SortIncludes: Never
#include "B/A.h"
#include "A/B.h"
#include "a/b.h"
#include "A/b.h"
#include "B/a.h"
// SortIncludes: CaseSensitive
#include "A/B.h"
#include "A/b.h"
#include "B/A.h"
#include "B/a.h"
#include "a/b.h"
// SortIncludes: SI_CaseInsensitive
#include "A/B.h"
#include "A/b.h"
#include "a/b.h"
#include "B/A.h"
#include "B/a.h"
控制排序using声明的方式
// SortUsingDeclarations: Never
using std::chrono::duration_cast;
using std::move;
using boost::regex;
using boost::regex_constants::icase;
using std::string;
// SortUsingDeclarations: Lexicographic
using boost::regex;
using boost::regex_constants::icase;
using std::chrono::duration_cast;
using std::move;
using std::string;
// SortUsingDeclarations: LexicographicNumeric
using boost::regex;
using boost::regex_constants::icase;
using std::move;
using std::string;
using std::chrono::duration_cast;
c风格的强制转换是否添加空格
// SpaceAfterCStyleCast: false
(int)i;
// SpaceAfterCStyleCast: true
(int) i;
是否在逻辑非运算符号(!)后面添加一个空格
// SpaceAfterLogicalNot: false
if (!true)
{
dosomething();
}
// SpaceAfterLogicalNot: true
if (! true)
{
dosomething();
}
template关键字后面是否加空格
// SpaceAfterTemplateKeyword: false
template
void Func(T a)
{
}
// SpaceAfterTemplateKeyword: true
template
void Func(T a)
{
}
指针限定符附近是否放置空格
// 设置PointerAlignment为Left
// SpaceAroundPointerQualifiers: Default
void* const* x = NULL;
// SpaceAroundPointerQualifiers: Before
void* const* x = NULL;
// SpaceAroundPointerQualifiers: After
void* const * x = NULL;
// SpaceAroundPointerQualifiers: Both
void* const * x = NULL;
// 设置PointerAlignment为Right
// SpaceAroundPointerQualifiers: Default
void *const *x = NULL;
// SpaceAroundPointerQualifiers: Before
void * const *x = NULL;
// SpaceAroundPointerQualifiers: After
void *const *x = NULL;
// SpaceAroundPointerQualifiers: Both
void * const *x = NULL;
赋值符号的左边是否添加空格
// SpaceBeforeAssignmentOperators: false
int a= 5;
a+= 42;
// SpaceBeforeAssignmentOperators: true
int a = 5;
a += 42;
是否添加case冒号之前的空格
// SpaceBeforeCaseColon: false
switch (a)
{
case 1:
break;
case 2:
break;
default:
break;
}
// SpaceBeforeCaseColon: true
switch (a)
{
case 1 :
break;
case 2 :
break;
default :
break;
}
设置为true时,使用c++11的包围列表初始化的大括号左边会添加一个空格
// SpaceBeforeCpp11BracedList: false
std::vector a{1, 2, 3};
// SpaceBeforeCpp11BracedList: true
std::vector a {1, 2, 3};
是否添加构造函数中初始化列表的冒号前的空格
// SpaceBeforeCtorInitializerColon: false
struct MyClass
{
MyClass(): m_a(0), m_b(0) {}
int m_a;
int m_b;
};
// SpaceBeforeCtorInitializerColon: true
struct MyClass
{
MyClass() : m_a(0), m_b(0) {}
int m_a;
int m_b;
};
是否添加继承的冒号前的空格
// SpaceBeforeInheritanceColon: false
class Foo: Bar
{
}
// SpaceBeforeInheritanceColon: true
class Foo : Bar
{
}
定义是否添加圆括号前面的空格。当设置为Custom时,使用SpaceBeforeParensOptions字段的定义
// SpaceBeforeParens: Never
void foo()
{
dosomething();
dosomething();
}
if(0)
{
}
func1();
func2(a, b);
std::for_each(vec.begin(), vec.end(), [](int) {});
// SpaceBeforeParens: ControlStatements
void foo()
{
dosomething();
dosomething();
}
if (0)
{
}
func1();
func2(a, b);
std::for_each(vec.begin(), vec.end(), [](int) {});
// SpaceBeforeParens: ControlStatementsExceptControlMacros
void foo()
{
dosomething();
dosomething();
}
if (0)
{
}
func1();
func2(a, b);
std::for_each(vec.begin(), vec.end(), [](int) {});
// SpaceBeforeParens: NonEmptyParentheses
void foo()
{
dosomething();
dosomething();
}
if (0)
{
}
func1();
func2 (a, b);
std::for_each (vec.begin(), vec.end(), [] (int) {});
// SpaceBeforeParens: Always
void foo ()
{
dosomething ();
dosomething ();
}
if (0)
{
}
func1 ();
func2 (a, b);
std::for_each (vec.begin (), vec.end (), [] (int) {});
定义是否添加圆括号前面的空格,需要设置SpaceBeforeParens为Custom
AfterControlStatements
// AfterControlStatements: false
if(0)
{
}
// AfterControlStatements: true
if (0)
{
}
AfterForeachMacros
没有生效,不知道原因
AfterFunctionDefinitionName
// AfterFunctionDefinitionName: false
void Func()
{
dosomething();
dosomething();
}
void Func(int a, int b)
{
dosomething();
dosomething();
}
// AfterFunctionDefinitionName: true
void Func ()
{
dosomething();
dosomething();
}
void Func (int a, int b)
{
dosomething();
dosomething();
}
AfterFunctionDeclarationName
// AfterFunctionDeclarationName: false
void Func();
void Func(int a, int b);
// AfterFunctionDeclarationName: true
void Func ();
void Func (int a, int b);
AfterIfMacros
没有生效,不知道原因
AfterOverloadedOperator
// AfterOverloadedOperator: false
void operator++(int a);
// AfterOverloadedOperator: true
void operator++ (int a);
AfterRequiresInClause
// AfterRequiresInClause: false
template
requires(A && B)
{
}
// AfterRequiresInClause: true
template
requires (A && B)
{
}
AfterRequiresInExpression
// AfterRequiresInExpression: false
template
concept C = requires(T t) {
...;
...;
}
// AfterRequiresInExpression: true
concept C = requires (T t) {
...;
...;
}
BeforeNonEmptyParentheses
// BeforeNonEmptyParentheses: false
void Func();
void Func(int a, int b);
// BeforeNonEmptyParentheses: true
void Func();
void Func (int a, int b);
设置基于范围的for循环冒号左边是否添加空格
// SpaceBeforeRangeBasedForLoopColon: false
for (auto a: vec)
{
}
// SpaceBeforeRangeBasedForLoopColon: true
for (auto a : vec)
{
}
控制方括号[]前是否添加括号,lambda函数的方括号不受影响
// SpaceBeforeSquareBrackets: false
int a[5][5];
// SpaceBeforeSquareBrackets: true
int a [5][5];
空代码块是否添加空格
// SpaceInEmptyBlock: false
void f() {}
// SpaceInEmptyBlock: true
void f() { }
尾部注释的空格数量
// SpacesBeforeTrailingComments: 4
int a; // comment
int b; // comment
int c; /* comment */
模版参数列表是否添加空格
// SpacesInAngles: Never
std::function fct;
// SpacesInAngles: Always
std::function< void(int) > fct;
// SpacesInAngles: Leave
// 如果有一个空格,则保持不变
std::function< void(int)> fct;
控制单行注释的空格数量,有Minimum和Maximum两个选项,Maximum可以设置为-1来表示禁用最大值
// SpacesInLineCommentPrefix:
// Minimum: 2
// Maximum: 5
// comment1
// comment2
// comment3
// comment4
定义左括号后和右括号前是否有空格,可以定义为Never或者Custom,如果定义为Custom,那么使用SpacesInParensOptions的定义
// SpacesInParens: Never
void foo()
{
if (true && 1)
{
f();
}
}
控制左括号后和右括号前是否有空格,需要定义SpacesInParens为Custom
InCStyleCasts: C风格强转是否有空格
// InCStyleCasts: false
x = (int)y;
// InCStyleCasts: true
x = ( int )y;
InConditionalStatements: 条件语句(for/if/while/switch...)是否有空格
// InConditionalStatements: false
if (a)
{
dosomething();
}
while (i < 5)
{
dosomething();
}
// InConditionalStatements: true
if ( a )
{
dosomething();
}
while ( i < 5 )
{
dosomething();
}
InEmptyParentheses: 空括号是否有空格
// InEmptyParentheses: false
void foo()
{
if (true)
{
f();
}
}
// InEmptyParentheses: true
void foo( )
{
if (true)
{
f( );
}
}
Other: 除去上述选项的其他情况是否添加空格
// Other: false
void Func(int a, int b);
// Other: true
void Func( int a, int b );
方括号内是否添加空格,没有参数的lambda函数和没有指定大小的数组不受影响
// SpacesInSquareBrackets: false
int a[5];
int b[];
auto func1 = []() { return 1 };
auto func1 = [&]() { return 1 };
// SpacesInSquareBrackets: true
int a[ 5 ];
int b[];
auto func1 = []() { return 1 };
auto func1 = [ & ]() { return 1 };
解析并格式化与此标准兼容的c++格式
// Standard: c++03
std::vector > x;
// Latest
std::vector> x;
忽略语句前面的宏,把它们看作一个属性
把定义的宏解释为一个完整的语句
指定制表符的宽度
是否使用制表符,可选Never、ForIndentation、ForContinuationAndIndentation、AlignWithSpaces、Always等
指定对空白字符敏感的宏