Clang-Format 样式选项
Clang-Format 样式选项 描述了LibFormat和 ClangFormat支持的可配置格式样式选项。
当我们使用clang-format命令行工具,或者在代码里调用clang::format::reformat(...)
方法时,可以指定 (LLVM, Google, Chromium, Mozilla, WebKit)中的一种预定义样式,也可以通过配置的特定选项创建自定义样式
使用clang-format配置样式
clang-format支持两种提供自定义样式选项的方法:
1.在命令行选项中直接通过-style =
指定样式配置
clang-format -style=llvm test.m
2.在项目目录中创建.clang-format或_clang-format文件用来存放自定义样式配置选项,并通过命令行选项-style=file
指定自定义文件
clang-format -style=file test.m
.clang-format
文件使用YAML格式:
key1:value1
key2:value2
#注释
...
这个配置文件可以包含多个sections,每个section可以指定不同的Language:
参数,来表示这个section所针对的编程语言;有关支持的语言列表,请参见下边的语言选项说明.
⊙一个多语言配置文件的示例
---
# We'll use defaults from the LLVM style, but with 4 columns indentation.
BasedOnStyle: LLVM
IndentWidth: 4
---
Language: Cpp
# Force pointers to the type for C++.
DerivePointerAlignment: false
PointerAlignment: Left
---
Language: JavaScript
# Use 100 columns for JS.
ColumnLimit: 100
---
Language: Proto
# Don't format .proto files.
DisableFormat: true
...
第一部分没有指定语言,它会对所有语言设置默认风格选项(LLVM),指定语言的配置部分(设置了language
)将会覆盖默认部分的设置选项;
当使用clang-format格式化一个文件时,它会使用文件名自动检测该文件使用的语言,但是当该文件的扩展名没有相对应的语言时,使用assume-filename=
的选项,来覆盖通过文件名判断语言的逻辑
-assume-filename=/usr/local/objc/.clang-format
获取包含特定预定义样式的所有配置选项的有效.clang-format
文件的简单方法:
clang-format -style=llvm -dump-config > .clang-format
当使用-style=
选项来指定配置时,也可以使用与.clang-format相同的配置格式,来进行配置,格式为:
-style='{key1:value2,key2:value2,...}'
禁用一段代码的格式化
Clang-format允许在特定的代码区间,以//clang-format off或/clang-format off/为开头,以//clang-format on或/clang-format on/为结尾,这段范围内的代码无法被格式化,但是注释本身会被正常格式化(对齐)
int formatted_code;
// clang-format off
void unformatted_code ;
// clang-format on
void formatted_code_again;
在代码中配置样式
当使用 clang::format::reformat(...)
方法时, 通过clang::format::FormatStyle结构体来指定格式
clang::format::FormatStyle format = clang::format::getLLVMStyle();
clang::format::reformat(format, code, ranges, filename);
可配置的格式样式选项
本节列出了所有支持的样式选项,每个选项都指定了不同的值类型,例如对于枚举类型,值既可能是c++的枚举成员,也可能是配置中的可用值;
BaseOnStyle(string
)
这个属性代表使用哪套选项模板
仅在clang-format配置中使用(-style={...}
和.clang-format
)
可能的值:
-
LLVM
符合LLVM编码标准的样式 -
Google
符合Google的C ++的风格指南样式 -
Chromium
符合Chromium的风格指南样式 -
Mozilla
符合Mozilla的风格指南样式 -
WebKit
符合WebKit的风格指南样式
AccessModifierOffset (int
)
访问修饰符的缩进
values:
- 0
@private
@property (nonatomic,strong)NSString *str;
- 4
@private
@property (nonatomic,strong)NSString *str;
AlignAfterOpenBracket (BracketAlignmentStyle)
如果设置了这个选项,则在左括号后进行水平对齐
这同样适用于圆括号,尖括号,方括号,()
<>
[]
换行规则根据最大代码列数
ColumnLimit
来判断
-
BAS_Align
(配置项中对应Align
),对齐括号里的参数
someLongFunction(argument1,
argument2);
-
BAS_DontAlign
(配置项对应DontAlign
)不对齐,而是使用缩进ContinuationIndentWidth
对齐,比如ContinuationIndentWidth=4
someLongFunction(argument1,
argument2);
-
BAS_AlwayBreak
(配置项对应AlwaysBreak
),如果参数不适合单行,则在左括号后换行
someLongFunction(
argument1, argument2);
AlignConsecutiveAssignments (bool
)
如果为true,则对齐连续行的赋值操作符
int aaaa = 12;
int b = 23;
int ccc = 23;
AlignConsecutiveDeclarations (bool
)
如果为true,则对齐连续行的声明的变量
int aaaa = 12;
float b = 23;
std::string ccc = 23;
AlignEscapedNewlines (EscapedNewlineAlignmentStyle
)
用于在转义换行符中对齐反斜杠的选项。
-
ENAS_DontAlign
(配置项对应DontAlign
),不对齐反斜杠
#define A \
int aaaa; \
int b; \
int dddddddddd;
-
ENAS_Left
(配置项对应Left
),尽可能的远的对齐反斜杠
#define A \
int aaaa; \
int b; \
int dddddddddd;
-
ENAS_Right
(配置项对应'Right'),在最大列处对齐反斜杠
#define A \
int aaaa; \
int b; \
int dddddddddd;
AlignOperands (bool
)
如果为true,则水平对齐二元或三元表达式
具体来说,这将对齐需要拆分成多行的单行表达式
int aaa = bbbbbbbbbbbbbbb +
ccccccccccccccc;
AlignTrailingComments (bool
)
如果为ture,则对齐注释
true: false:
int a; // My comment a vs. int a; // My comment a
int b = 2; // comment b int b = 2; // comment about b
AllowAllParametersOfDeclarationOnNextLine (bool
)
如果函数不适合一行展示,将函数的所有参数放到下一行,即使BinPackParameters为false
true:
void myFunction(
int a, int b, int c, int d, int e);
false:
void myFunction(int a,
int b,
int c,
int d,
int e);
AllowShortBlocksOnASingleLine (bool
)
当值为true允许将简单的括号语句收缩到一行。
if (flag) { return; }
AllowShortCaseLabelsOnASingleLine (bool
)
当值为true,允许短case语句收缩成一行
true: false:
switch (a) { vs. switch (a) {
case 1: x = 1; break; case 1:
case 2: return; x = 1;
} break;
case 2:
return;
}
AllowShortFunctionsOnASingleLine (ShortFunctionStyle
)
不同的枚举值,可以决定短方法的不同样式
-
SFS_None
(配置项对应None
),永不将函数合并为一行 -
SFS_InlineOnly
(配置项对应InlineOnly
),只合并定义在class中的短方法
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {
}
-
SFS_Empty
(配置项对应Empty
),只合并空函数
void f() {}
void f2() {
bar2();
}
-
SFS_Inline
(配置项对应Inline
),只合并定义在class中的短方法,和空方法
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {}
-
SFS_All
(配置项对应All
),合并所有适合一行展示的函数
class Foo {
void f() { foo(); }
};
void f() { bar(); }
AllowShortIfStatementsOnASingleLine (bool
)
如果为true,可以将短的声明语句收缩至一行
if(flag) return;
AllowShortLoopsOnASingleLine (bool
)
如果为ture,可以将短的循环语句收缩成一行
while (true) continue;
AlwaysBreakAfterDefinitionReturnType(DefinitionReturnTypeBreakingStyle
)
DefinitionReturnTypeBreakingStyle
)已废弃
AlwaysBreakAfterReturnType (ReturnTypeBreakingStyle
)
函数中,返回声明的样式
ps:一般设置None,因为返回值声明后需要换行很少见
-
RTBS_None
(配置项对应None
),意味着不换行
class A {
int f() { return 0; };
};
int f();
int f() { return 1; }
-
RTBS_All
(配置项对应All
),返回值声明后总是要换行
class A {
int
f() {
return 0;
};
};
int
f();
int
f() {
return 1;
}
-
RTBS_TopLevel
(配置项对应TopLevel
),总是在全局函数声明的返回值后换行[原文:Always break after the return types of top-level functions,这里的top-level functions翻译成全局函数不知道对不对]
class A {
int f() { return 0; };
};
int
f();
int
f() {
return 1;
}
-
RTBS_AllDefinitions
(配置项对应AllDefinitions
),总是在实现的函数返回值定义处换行
class A {
int
f() {
return 0;
};
};
int f();
int
f() {
return 1;
}
-
RTBS_TopLevelDefinitions
(配置项对应TopLevelDefinitions
),总是在全局函数里的已实现函数的返回值处换行
class A {
int f() { return 0; };
};
int f();
int
f() {
return 1;
}
AlwaysBreakBeforeMultilineStrings (bool
)
如果为true,则在多行定义字符串之前换行
true: false:
aaaa = vs. aaaa = "bbbb"
"bbbb" "cccc";
"cccc";
AlwaysBreakTemplateDeclarations (BreakTemplateDeclarationsStyle
)
要使用的模板声明中的换行样式
-
BTDS_No
(配置项对应No
),在声明之前不强制换行
template <typename T> T foo() {
}
template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
int bbbbbbbbbbbbbbbbbbbbb) {
}
-
BTDS_MultiLine
(配置项对应MultiLine
),仅在以下声明跨越多行时才强制在模板声明之后换行
template <typename T> T foo() {
}
template <typename T>
T foo(int aaaaaaaaaaaaaaaaaaaaa,
int bbbbbbbbbbbbbbbbbbbbb) {
}
-
BTDS_Yes
(配置项对应Yes
),总是在模板声明后换行
template <typename T>
T foo() {
}
template <typename T>
T foo(int aaaaaaaaaaaaaaaaaaaaa,
int bbbbbbbbbbbbbbbbbbbbb) {
}
BinPackArguments (bool
)
如果false,函数调用的参数将在同一行上,或者每个都有一行。
true:
void f() {
f(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
}
false:
void f() {
f(aaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
}
BinPackParameters (bool
)
如果为false,则函数声明或函数定义的参数将全部在同一行上,或者每行都有一行。
true:
void f(int aaaaaaaaaaaaaaaaaaaa, int aaaaaaaaaaaaaaaaaaaa,
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}
false:
void f(int aaaaaaaaaaaaaaaaaaaa,
int aaaaaaaaaaaaaaaaaaaa,
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}
BraceWrapping (BraceWrappingFlags
)
控制着花括号的样式
如果想要这个选项生效,必须将
BreakBeforeBraces
设置为BS_Custom
(配置项对应Custom
)
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: true
AfterStruct: false
SplitEmptyFunction: false
以下可选值都是bool
类型
-
AfterClass
决定类定义处换行
true:
class foo
{};
false:
class foo{};
//这个示例文档是错误的,这里已经更正
-
AfterControlStatement
决定在(if/for/while/switch/@autoreleasepool/@synchronized..)处换行
true:
if (foo())
{
} else
{}
for (int i = 0; i < 10; ++i)
{}
false:
if (foo()) {
} else {
}
for (int i = 0; i < 10; ++i) {
}
-
AfterEnum
决定在枚举定义处换行
true:
enum X : int
{
B
};
false:
enum X : int { B };
-
AfterFunction
决定在方法定义处换行
true:
void foo()
{
bar();
bar2();
}
false:
void foo() {
bar();
bar2();
}
-
AfterNamespace
决定在命名空间定义处换行
true:
namespace
{
int foo();
int bar();
}
false:
namespace {
int foo();
int bar();
}
-
AfterObjCDeclaration
决定在ObjC定义处(interfaces,implementations)是否换行
true:
@interface XXX ()
{ NSString *_str; }
@end
@implementation XXX
{}
false:
@interface XXX () {
NSString *_str;
}
@end
@implementation XXX {
}
-
AfterStruct
决定在结构体定义处是否换行
true:
struct foo
{
int x;
};
false:
struct foo {
int x;
};
-
AfterUnion
决定在联合体定义处是否换行
true:
union foo
{
int x;
}
false:
union foo {
int x;
}
-
AfterExternBlock
决定在extern处是否换行
true:
extern "C"
{
int foo();
}
false:
extern "C" {
int foo();
}
/*extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。
加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。*/
-
BeforeCatch
决定在try-catch的catch前是否换行
true:
try {
foo();
}
catch () {
}
false:
try {
foo();
} catch () {
}
-
BeforeElse
决定在else前是否换行
true:
if (foo()) {
}
else {
}
false:
if (foo()) {
} else {
}
-
IndentBraces
花括号自身缩进
true:
if ()
{
}
false:
if ()
{
}
-
SplitEmptyFunction
如果值为false,那么空函数体可以放在一行;
如果想要值为false时生效,必须使
AfterFunction
为true并且AllowShortFunctionsOnASingleLine
为None
false true
int f() vs. inf f()
{} {
}
-
SplitEmptyRecord
如果为false,则可以将例如class/struct/union空实现放入单独一行;
如果想要值为false时生效,必须使
AfterClass
为true
class Foo vs. class Foo
{} {
}
-
SplitEmptyNamespace
如果为false,则可以使空的命名空间实现放在一行
如果想要值为false时生效,必须使
AfterNamespace
为 true
namespace Foo vs. namespace Foo
{} {
}
BreakAfterJavaFieldAnnotations(bool
)
在Java文件中的字段上的每个注释之后中断。
true: false:
@Partial vs. @Partial @Mock DataLoad loader;
@Mock
DataLoad loader;
BreakBeforeBinaryOperators (BinaryOperatorStyle
)
二元运算符的格式控制
-
BOS_None
(配置项对应:None
),在二元操作符之后换行
LooooooooooongType loooooooooooooooooooooongVariable =
someLooooooooooooooooongFunction();
bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >
ccccccccccccccccccccccccccccccccccccccccc;
-
BOS_NonAssignment
(配置项对应NonAssignment
),在二元操作符之前换行,赋值运算符''=''除外
LooooooooooongType loooooooooooooooooooooongVariable =
someLooooooooooooooooongFunction();
bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
== aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
&& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
> ccccccccccccccccccccccccccccccccccccccccc;
-
BOS_All
(配置项对应All
),在所有的二元操作符之前换行
LooooooooooongType loooooooooooooooooooooongVariable
= someLooooooooooooooooongFunction();
bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
== aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
&& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
> ccccccccccccccccccccccccccccccccccccccccc;
BreakBeforeBraces (BraceBreakingStyle
)
控制括号换行风格
*BS_Attach
(配置项对应Attach
),始终将括号依附在上下文当中
try {
foo();
} catch () {
}
void foo() { bar(); }
class foo {};
if (foo()) {
} else {
}
enum X : int { A, B };
-
BS_Linux
(配置项对应Linux
),类似Attach
,但是在function,namespace,class定义的括号前换行
try {
foo();
} catch () {
}
void foo() {
bar();
}
class foo
{
};
if (foo()) {
} else {
}
enum X : int { A, B };
-
BS_Mozilla
(配置项对应Mozilla
),类似Attach
,但是在enum,function,record的括号前换行
try {
foo();
} catch () {
}
void foo() {
bar();
}
class foo
{
};
if (foo()) {
} else {
}
enum X : int
{
A,
B
};
-
BS_Stroustrup
(配置项对应Stroustrup
),类似Attach
,但是在function,catch,else前换行
try {
foo();
}
catch () {
}
void foo()
{
bar();
}
class foo {
};
if (foo()) {
}
else {
}
enum X : int { A, B };
-
BS_Allman
(配置项对应Allman
),总是在括号前换行
try
{
foo();
}
catch ()
{
}
void foo()
{
bar();
}
class foo
{
};
if (foo())
{
}
else
{
}
enum X : int
{
A,
B
};
-
BS_GNU
(配置项对应GUN
)
BreakBeforeTernaryOperators (bool
)
如果为true,则在三元算符之前换行
true:
veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription
? firstValue
: SecondValueVeryVeryVeryVeryLong;
false:
veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription ?
firstValue :
SecondValueVeryVeryVeryVeryLong;
BreakConstructorInitializers (BreakConstructorInitializersStyle
)
控制构造初始化函数样式
BCIS_BeforeColon
(对应配置项'BeforeColon'),在冒号之前逗号之后换行
Constructor()
: initializer1(),
initializer2()
BCIS_BeforeComma
(对应配置项'BeforeComma'),在冒号和逗号之前换行,并对其逗号和冒号
Constructor()
: initializer1()
, initializer2()
BCIS_AfterColon
(对应配置项'AfterColon'),在冒号和逗号之前换行
Constructor() :
initializer1(),
initializer2()
BreakInheritanceList (BreakInheritanceListStyle
)
控制多继承样式
BILS_BeforeColon
(对应配置项'BeforeColon'),在冒号之前逗号之后换行
class Foo
: Base1,
Base2
{};
BILS_BeforeComma
(对应配置项'BeforeComma'),在冒号和逗号之前换行,并对其逗号和冒号
class Foo
: Base1
, Base2
{};
BILS_AfterColon
(对应配置项'AfterColon'),在冒号和逗号之前换行
class Foo :
Base1,
Base2
{};
BreakStringLiterals (bool
)
是否允许在字符串常量中换行
true:
NSString *a = @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@"aaaaaaaaaaaaaaaaaadddd";
false:
NSString *a = @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddd";
ColumnLimit (unsigned
)
代码最大列数,值为0意味着不限制;
我在Xcode里设置的是80,Xcode会在第80列处有一条直线,如果编码时超过这条线就要注意了 image.png
CommentPragmas (std::string
)
可以通过正则表达式,来使特定的注释不受格式化影响
// CommentPragmas: '^ FOOBAR pragma:'
// Will leave the following line unaffected
#include <vector> // FOOBAR pragma: keepkeepkeepkeepkeepkeep
or
#include <vector> // keepkeepkeepkeepkeepkeepkeep
//keepkeepkeepkeep
CompactNamespaces (bool
)
如果为true,则连续的名称空间声明将在同一行上。 如果为false,则在新的一行上声明每个名称空间。
true:
namespace Foo { namespace Bar {
}}
false:
namespace Foo {
namespace Bar {
}
}
当true时候,如果命名空间不适合单行,则超出的将被换行
namespace Foo { namespace Bar {
namespace Extra {
}}}
ConstructorInitializerAllOnOneLineOrOnePerLine (bool
)
当true,如果构造函数初始化不适合一行显示,则每个初始化器独占一行
true:
FitsOnOneLine::Constructor()
: aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}
DoesntFit::Constructor()
: aaaaaaaaaaaaa(aaaaaaaaaaaaaa),
aaaaaaaaaaaaa(aaaaaaaaaaaaaa),
aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}
false:
FitsOnOneLine::Constructor()
: aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}
DoesntFit::Constructor()
: aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),
aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}
ConstructorInitializerIndentWidth (unsigned
)
用于设定构造函数和多继承的缩进长度
2
Constructor()
: aaaaaaaaaaaaa(aaaaaaaaaaaaaa),
aaaaaaaaaaaaa(aaaaaaaaaaaaaa),
aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {
}
4:
Constructor()
: aaaaaaaaaaaaa(aaaaaaaaaaaaaa),
aaaaaaaaaaaaa(aaaaaaaaaaaaaa),
aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {
}
ContinuationIndentWidth (unsigned
)
连续行的缩进长度
10
int i = // keepkeepkeepkeepkeepkeep
longFunction(arg);
Cpp11BracedListStyle (bool
)
如果为true,则花括号列表会被格式化为最适合c++11的花括号列表样式
重要区别:花括号列表内没有空格.右大括号前没有换行.使用continuation缩进而不是block缩进(从示例看起来,区别就是c++风格的紧邻左右大括号的内部没有空格)
true: false:
vector<int> x{1, 2, 3, 4}; vs. vector<int> x{ 1, 2, 3, 4 };
vector<T> x{{}, {}, {}, {}}; vector<T> x{ {}, {}, {}, {} };
f(MyMap[{composite, key}]); f(MyMap[{ composite, key }]);
new int[3]{1, 2, 3}; new int[3]{ 1, 2, 3 };
DerivePointerAlignment (bool
)
如果为true,则会分析当前文件中指针样式哪种样式占比大,则采用哪种样式,如果为false,则会根据PointerAlignment
来决定
例:
NSString* _str;
NSString* _str;
NSString* _str;
NSString *_str;
true:
NSString* _str;
NSString* _str;
NSString* _str;
NSString* _str;
PointerAlignment(bool
)
指针对齐样式
-
PAS_Left
(配置文件对应Left
),指针左对齐
int* a;
-
PAS_Right
(配置文件对应Right
),指针右对齐
int *a;
-
PAS_Middle
(配置文件对应Middle
),指针中间对齐
int * a;
DisableFormat (bool
)
是否完全禁用格式化
ExperimentalAutoDetectBinPacking (bool
)
注意:这是一个实验性选项,可能会被删掉或重命名。 请勿在配置文件等中使用此功能。使用风险由您自行承担。
FixNamespaceComments (bool
)
如果为true,clang-format会在命名空间定义结尾处添加注释,并修复无效的现有注释
true: false:
namespace a { vs. namespace a {
foo(); foo();
} // namespace a; }
ForEachMacros (std::vector<std::string>
)
声明一个迭代器宏
例如:
ForEachMacros:['BOOST_FOREACH']
int main ()
{
std :: string hello ( "Hello, world!" );
BOOST_FOREACH ( char ch , hello )
{
std :: cout << ch ;
}
return 0 ;
}
这不是特别理解,这根Clang-Format有啥关系?
原文:
ForEachMacros (std::vector<std::string>)
A vector of macros that should be interpreted as foreach loops instead of as function calls.
These are expected to be macros of the form:
FOREACH(<variable-declaration>, ...)
<loop-body>
In the .clang-format configuration file, this can be configured like:
ForEachMacros: ['RANGES_FOR', 'FOREACH']
For example: BOOST_FOREACH.
IncludeBlocks (IncludeBlocksStyle
)
可以根据值,将#include模块按分类进行划分排序
-
IBS_Preserve
(配置项对应Preserve
),分别对每个#include进行排序
#include "b.h" into #include "b.h"
#include <lib/main.h> #include "a.h"
#include "a.h" #include <lib/main.h>
-
IBS_Merge
(配置项对应Merge
),合并多个#include,并排序
#include "b.h" into #include "a.h"
#include "b.h"
#include <lib/main.h> #include <lib/main.h>
#include "a.h"
-
IBS_Regroup
(配置项对应Regroup
),合并多个#include,并排序,再然后根据类形优先级(category priority)分组。 请参阅IncludeCategories
#include "b.h" into #include "a.h"
#include "b.h"
#include <lib/main.h>
#include "a.h" #include <lib/main.h>
IncludeCategories (std::vector<IncludeCategory>
)
用正则表达式,表示不同类型的#include,用于排序#include
支持POSIX extended正则表达式
这些正则表达式用于#include 后的<>or""内的文件名相匹配.匹配到的文件名先按照其优先级升序排序,优先级相同时,再按照字母顺序排序
如果正则没有匹配到的.则将未匹配到的文件名的category的优先级指定为INT_MAX(最大).
源文件的header引入优先级为0,所以可以排在#include的最上边.如果你想让某些header引入排在最上边, 你也可以将其优先级设为负数
***LLVM的此项设置***
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '<[[:alnum:].]+>'
Priority: 4
- Regex: '.*'
Priority: 1
IncludeIsMainRegex (std::string
)
指定file-to-main-include映射中允许的后缀的正则表达式。
允许设置后缀的正则表达式,来指定main header;
""
表示任意后缀,"$"
表示无后缀.
如果此选项设置为“(_test)?$”,当main header为a.h时,a.cc,a_test.cc都将被视为main header,既a.cc,a_test.cc都将排在源文件最上边
IndentCaseLabels (bool
)
控制switch声明中的case缩进.
如果值为false,则使用与switch语句相同的缩进,case的语句缩进总是比case本身高一级;
false: true:
switch (fool) { vs. switch (fool) {
case 1: case 1:
bar(); bar();
break; break;
default: default:
plop(); plop();
} }
IndentPPDirectives (PPDirectiveIndentStyle
)
控制预处理指令缩进样式
-
PPDIS_None
(配置项对应None
),不做任何缩进
#if a
#ifdef b
#include <foo>
#elif d
#include <foo>
#else e
#include <foo>
#endif
#ifndef c
#endif
#endif
-
PPDIS_AfterHash
(配置项对应AfterHash
)
在hash(#if
,#ifdef
,#ifndef
,#elif
,#else
,#endif
)后缩进
原文: Indents directives after the hash.
#if a
# ifdef b
# include <foo>
# elif d
# include <foo>
# else e
# include <foo>
# endif
# ifndef c
# endif
#endif
IndentWidth (unsigned
)
缩进的列数
IndentWidth: 3
void f() {
someFunction();
if (true, false) {
f();
}
}
IndentWrappedFunctionNames (bool
)
如果为true,函数的定义或声明在返回值类型之后换行,则缩进
true:
LoooooooooooooooooooooooooooooooooooooooongReturnType
LoooooooooooooooooooooooooooooooongFunctionDeclaration();
false:
LoooooooooooooooooooooooooooooooooooooooongReturnType
LoooooooooooooooooooooooooooooooongFunctionDeclaration();
JavaScriptQuotes (JavaScriptQuoteStyle
)
控制JavaScript字符串的风格样式
-
JSQS_Leave
(配置项对应Leave
),不做更改,保留原有样式
string1 = "foo";
string2 = 'bar';
-
JSQS_Single
(配置项对应Single
),总是用单引号
string1 = 'foo';
string2 = 'bar';
-
JSQS_Double
(配置项对应Double
),总是用双引号
string1 = "foo";
string2 = "bar";
JavaScriptWrapImports ('bool')
决定JavaScript 的import/export声明是否需要换行
true:
import {
VeryLongImportsAreAnnoying,
VeryLongImportsAreAnnoying,
VeryLongImportsAreAnnoying,
} from 'some/module.js'
false:
import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js"
KeepEmptyLinesAtTheStartOfBlocks (bool
)
如果为true,则将代码块开始的首行的空行保留
true: false:
if (foo) { vs. if (foo) {
bar();
bar(); }
}
Language (LanguageKind
)
指定格式化风格作用在哪种语言
-
LK_None
(配置项对应None
) 不使用 -
LK_Cpp
(配置项对应Cpp
) C或C++. -
LK_Java
(配置项对应Java
) Java. -
LK_JavaScript
(配置项对应JavaScript
) JavaScript. -
LK_ObjC
(配置项对应ObjC
) Objective-C或Objective-C++. -
LK_Proto
(配置项对应Proto
) Protocol Buffers -
LK_TableGen
(配置项对应TableGen
)TableGen code. -
LK_TextProto
(配置项对应TextProto
) Protocol Buffer messages in text format
MacroBlockBegin (std::string
),MacroBlockEnd (std::string
)
正则表达式定义宏的开始于结束块
# With:
MacroBlockBegin: "^NS_MAP_BEGIN|\
NS_TABLE_HEAD$"
MacroBlockEnd: "^\
NS_MAP_END|\
NS_TABLE_.*_END$"
NS_MAP_BEGIN
foo();
NS_MAP_END
NS_TABLE_HEAD
bar();
NS_TABLE_FOO_END
# Without:
NS_MAP_BEGIN
foo();
NS_MAP_END
NS_TABLE_HEAD
bar();
NS_TABLE_FOO_END
MaxEmptyLinesToKeep (unsigned
)
控制最大的连续空行
MaxEmptyLinesToKeep: 1 vs. MaxEmptyLinesToKeep: 0
int f() { int f() {
int = 1; int i = 1;
i = foo();
i = foo(); return i;
}
return i;
}
NamespaceIndentation (NamespaceIndentationKind
)
namespaces的缩进
-
NI_None
(配置项对应None
),不缩进
namespace out {
int i;
namespace in {
int i;
}
}
-
NI_Inner
(配置项对应Inner
),只在嵌套的namespaces中缩进
namespace out {
int i;
namespace in {
int i;
}
}
-
NI_All
(配置项对应All
),所有的namespaces都缩进
namespace out {
int i;
namespace in {
int i;
}
}
ObjCBinPackProtocolList (BinPackStyle
)
当ObjC的协议列表超过代码最大列数(ColumnLimit
)限制,同过此选项,控制协议列表的组合样式.
-
BPS_Auto
(配置项对应Auto
),会根据BinPackParameters
的值,如果其为true,则当代码超过ColumnLimit
时,会按最少行的规则去组合协议列表
(Auto && BinPackParameters=true):
@interface ccccccccccccc () <
ccccccccccccc, ccccccccccccc,
ccccccccccccc, ccccccccccccc> {
}
-
BPS_Always
(配置项对应Always
),当代码超过ColumnLimit
时,会按最少行的规则去组合协议列表
@interface ccccccccccccc () <
ccccccccccccc, ccccccccccccc,
ccccccccccccc, ccccccccccccc> {
}
-
BPS_Never
(配置项对应Never
),当代码超过ColumnLimit
时,会按每个协议都单独一行的规则去显示
@interface ddddddddddddd () <
ddddddddddddd,
ddddddddddddd,
ddddddddddddd,
ddddddddddddd> {
}
在clang-format version 6.0.1没有此选项,应该被移除了
todo:待在7.0版本验证以上和BinPackParameters的不同值组合
ObjCBlockIndentWidth (unsigned
)
控制ObjC的代码块(Block)实现的缩进
ObjCBlockIndentWidth: 4
[operation setCompletionBlock:^{
[self onOperationDone];
}];
ObjCSpaceAfterProperty (bool
)
ObjC里,在@property后加空格
true:
@property (readonly)
false:
@property(readonly)
ObjCSpaceBeforeProtocolList (bool
)
ObjC里,在协议列表前加空格
true:
@interface Foo() <Protocol>
false:
@interface Foo()<Protocol>
PenaltyBreakAssignment (unsigned
)
The penalty for breaking around an assignment operator.
PenaltyBreakBeforeFirstCallParameter (unsigned
)
The penalty for breaking a function call after call(.
PenaltyBreakComment (unsigned
)
The penalty for each line break introduced inside a comment.
PenaltyBreakFirstLessLess (unsigned
)
The penalty for breaking before the first <<.
PenaltyBreakString (unsigned
)
The penalty for each line break introduced inside a string literal.
PenaltyBreakTemplateDeclaration (unsigned
)
The penalty for breaking after template declaration.
PenaltyExcessCharacter (unsigned
)
The penalty for each character outside of the column limit.
PenaltyReturnTypeOnItsOwnLine (unsigned
)
Penalty for putting the return type of a function onto its own line.
以上几个太难猜了,还没有示例,不知道啥意思,等知道了再补充
RawStringFormats (std::vector<RawStringFormat>
)
待补充
ReflowComments (bool
)
如果为true,则clang-format会尝试对单条注释折行
false:
// veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
/* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */
true:
// veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
// information
/* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
* information */
SortIncludes (bool
)
如果为true,则会对#include进行排序
false: true:
#include "b.h" vs. #include "a.h"
#include "a.h" #include "b.h"
SortUsingDeclarations (bool)
如果为true,则会对声明进行排序
false: true:
using std::cout; vs. using std::cin;
using std::cin; using std::cout;
SpaceAfterCStyleCast (bool
)
如果为true,则会在C语言类型的类型转换后插入空格
true: false:
(int) i; vs. (int)i;
SpaceAfterTemplateKeyword (bool
)
如果为true,则会在'template'关键字后插入一个空格。
true: false:
template <int> void foo(); vs. template<int> void foo();
SpaceBeforeAssignmentOperators (bool
)
如果为false,则会在赋值运算符=前移除空格
true: false:
int a = 5; vs. int a=5;
a += 42 a+=42;
SpaceBeforeCpp11BracedList (bool
)
如果为true,则在用于初始化对象的C ++ 11括号列表之前插入空格(在前前置标识符(preceding identifier)或类型之后)。
true: false:
Foo foo { bar }; vs. Foo foo{ bar };
Foo {}; Foo{};
vector<int> { 1, 2, 3 }; vector<int>{ 1, 2, 3 };
new int[3] { 1, 2, 3 }; new int[3]{ 1, 2, 3 };
SpaceBeforeCtorInitializerColon (bool
)
如果为false,则在构造函数初始化器冒号之前将删除空格。
true: false:
Foo::Foo() : a(a) {} Foo::Foo(): a(a) {}
SpaceBeforeInheritanceColon (bool
)
如果为false,则在继承冒号之前将删除空格。
true: false:
class Foo : Bar {} vs. class Foo: Bar {}
SpaceBeforeParens (SpaceBeforeParensOptions
)
定义在左括号前插入空格的情况
-
SBPO_Never
(配置项对应Never
),永远不会在左括号前插入空格
void f() {
if(true) {
f();
}
}
-
SBPO_ControlStatements
(配置项对应ControlStatements
),在控制语句关键字(for / if / while ...)之后的左括号前插入一个空格
void f() {
if (true) {
f();
}
}
-
SBPO_Always
(配置项对应Always
),总是在左括号前插入一个空格
void f () {
if (true) {
f ();
}
}
SpaceBeforeRangeBasedForLoopColon (bool
)
如果为false,则在基于范围的for循环冒号之前将删除空格。
true: false:
for(auto v : values) {} vs. for(auto v: values) {}
SpaceInEmptyParentheses (bool
)
如果为true,则可以在()中插入空格。
true: false:
void f( ) { vs. void f() {
int x[] = {foo( ), bar( )}; int x[] = {foo(), bar()};
if (true) { if (true) {
f( ); f();
} }
} }
SpacesBeforeTrailingComments (unsigned
)
尾随行注释(//)之前的空格数。
这不会影响尾随块注释(/* */),因为它们通常具有不同的使用模式和许多特殊情况。
SpacesBeforeTrailingComments: 3
void f() {
if (true) { // foo1
f(); // bar
} // foo
}
SpacesInAngles (bool
)
如果为true,则会在模板参数列表中的<之后和>之前插入空格
true: false:
static_cast< int >(arg); vs. static_cast<int>(arg);
std::function< void(int) > fct; std::function<void(int)> fct;
SpacesInCStyleCastParentheses (bool
)
如果为true,则可以将空格插入到C语言样式的类型转换中。
true: false:
x = ( int32 )y vs. x = (int32)y
SpacesInContainerLiterals (bool
)
如果为true,则在字面量容器内插入空格(例如ObjC和JavaScript里的array和dict)
true: false:
var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3];
f({a : 1, b : 2, c : 3}); f({a: 1, b: 2, c: 3});
SpacesInParentheses (bool
)
如果为true,则在'('之后,')'之前插入空格。
true: false:
t f( Deleted & ) & = delete; vs. t f(Deleted &) & = delete;
SpacesInSquareBrackets (bool
)
如果为true,则在"["之后,"]"之前插入空格。 Lambdas或未指定大小的数组声明不会受到影响。
true: false:
int a[ 5 ]; vs. int a[5];
std::unique_ptr<int[]> foo() {} // 不受影响
Standard (LanguageStandard
)
设置一种标准来对格式兼容,例如 设置LS_Cpp03,使用A<A<int> >
来兼容A<A<int>>
。
-
LS_Cpp03
(配置项对应Cpp03
),使用C ++ 03兼容语法。 -
LS_Cpp11
(配置项对应Cpp11
) 使用它 C++11, C++14 , C++1z的特性(例如A<A<int>>
来兼容A<A<int> >
) -
LS_Auto
(配置项对应Auto
),基于输入自动检测。
TabWidth (unsigned
)
设置制表符(\t)的列数
UseTab (UseTabStyle
)
-
UT_Never
(配置项对应Never
)从不使用制表符 -
UT_ForIndentation
(配置项对应ForIndentation
) ,只在缩进时,使用制表符 -
UT_ForContinuationAndIndentation
(配置项对应ForContinuationAndIndentation
),仅使用制表符用于连续行和缩进。 -
UT_Always
(配置项对应Always
) ,每当我们需要填充至少从一个制表位到下一个制表位的空白时,请使用制表符
使用例子:
-
linux内核样式类似的样式
BasedOnStyle: LLVM
IndentWidth: 8
UseTab: Always
BreakBeforeBraces: Linux
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
void test()
{
switch (x) {
case 0:
case 1:
do_something();
break;
case 2:
do_something_else();
break;
default:
break;
}
if (condition)
do_something_completely_different();
if (x == y) {
q();
} else if (x > y) {
w();
} else {
r();
}
}
-
默认Visual Studio格式样式的类似样式
UseTab: Never
IndentWidth: 4
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
ColumnLimit: 0
void test()
{
switch (suffix)
{
case 0:
case 1:
do_something();
break;
case 2:
do_something_else();
break;
default:
break;
}
if (condition)
do_somthing_completely_different();
if (x == y)
{
q();
}
else if (x > y)
{
w();
}
else
{
r();
}
}
网友评论