使用clang-format对iOS项目代码进行格式化
公司的项目已经迭代了近两年,在两年的时间里不断的有新人参加到项目里,每个人都有自己的代码风格,随着项目越来越大,没有统一代码规范带来的维护问题也越来越多,所以和小组的同事商量了下制定了iOS的编码规范。
规范总是要执行才能生效,不过几千字的编码规范总不能每次写代码前都熟读一遍吧,翻了下Package Manager,发现CLangFormat可以根据代码规范格式化代码。具体的使用方式已经有大神非常详尽地介绍,感兴趣的同学请移步《iOS 代码格式化管理》—Bannings的专栏。
看了《iOS 代码格式化管理》后发现我们当前还需要解决两个问题:一个是自定义符合我们团队的代码规范;另外一个是根据规范整理以前写的代码。
第一个问题 在《iOS 代码格式化管理》中已经介绍过,主要是配置.clang-format文件,让CLangFormat根据自定义的配置格式化代码,这里贴出我们团队使用的.clang-format配置。因为.clang-format的配置选项非常多、有些选项的解释非常模糊,所以我们只测试了常用的选项,没用到的都注释了。
# document ref: http://clang.llvm.org/docs/ClangFormatStyleOptions.html
#禁用当前format文件
DisableFormat: false
BasedOnStyle: WebKit
#是否使用tab进行缩进
UseTab: Never
TabWidth: 4
IndentWidth: 4
#语言
Language: Cpp
Standard: Cpp11
#includeCategoriesStandard: Cpp11
#Cpp11BracedListStyle: false
#ForEachMacros
#IncludeCategories
#-----------------------file----------------------
#最大宽度,如果代码超过这个宽度会按语义折行
ColumnLimit: 130
#最多能超出ColumnLimit多少个字符
PenaltyExcessCharacter: 0
#允许最大连续空行数
MaxEmptyLinesToKeep: 10
#在续行(\
# 下一行)时的缩进长度
ContinuationIndentWidth: 4
#CommentPragmas: ''
#DerivePointerBinding: false
#--------------------------code block------------------
#括号的断行模式
BreakBeforeBraces: Mozilla
#是否在容器字面量(@[@"1",@"2"])中插入空格
SpacesInContainerLiterals: true
#case语句的位置总是在switch语句后缩进一级
IndentCaseLabels: true
#多行赋值语句按=号对齐
AlignConsecutiveAssignments: false
#多行声明语句按=号对齐
AlignConsecutiveDeclarations: false
#是否把注释右对齐,下面为右对齐的效果
#void someFunction() {
# doWork(); // Does something
# doMoreWork(); // Does something else
#}
AlignTrailingComments: true
#是否在括号前加上空格
SpaceBeforeParens: ControlStatements
#在未封闭(括号的开始和结束不在同一行)的括号中的代码是否对齐
# if(a &&
# b)
#
AlignAfterOpenBracket: Align
#类的访问修饰关键字(private,public,protected···)缩进
# private:
# int a;
# 1表示不缩进
#大于1的值表示访问修饰关键字的左侧从int a的左侧列开始往右侧移动的距离
#AccessModifierOffset: 1
#在构造函数初始化时按逗号断行,并以冒号对齐
BreakConstructorInitializersBeforeComma: false
#ConstructorInitializerAllOnOneLineOrOnePerLine: false
#ConstructorInitializerIndentWidth: 0
#ExperimentalAutoDetectBinPacking: false
#IndentWrappedFunctionNames: true
#IndentFunctionDeclarationAfterType: false
#AlignEscapedNewlinesLeft: true
#BinPackArguments: false
#BinPackParameters: false
#AllowAllParametersOfDeclarationOnNextLine: false
#----------------------sataement----------------
#指针在类型那边还是在变量名那边还是在中间
PointerAlignment: Right
#在=号前加空格
SpaceBeforeAssignmentOperators: true
#是否在空括号中加空格
SpaceInEmptyParentheses: false
#单行注释前的空格数
SpacesBeforeTrailingComments: 0
#是否在<>中间插入空格
SpacesInAngles: false
#是否在非空的括号中插入空格
SpacesInParentheses: false
#在三元运算符前断行
BreakBeforeTernaryOperators: true
#在二元运算符前断行
#BreakBeforeBinaryOperators: All
#是否允许短代码块在一行写完
#如 if (a) { return; }
AllowShortBlocksOnASingleLine: false
#是否允许短switch的case 语句在一行写完
AllowShortCaseLabelsOnASingleLine: true
#是否允许短的函数在一行写完
AllowShortFunctionsOnASingleLine: false
#是否允许短的语句在一行写完
AllowShortIfStatementsOnASingleLine: true
#是否允许短的循环在一行写完
AllowShortLoopsOnASingleLine: true
#命名空间缩进
#NamespaceIndentation: All
#AlignOperands: false
#PenaltyBreakBeforeFirstCallParameter: 100
#PenaltyBreakComment: 100
#PenaltyBreakFirstLessLess: 0
#PenaltyBreakString: 100
#-----------------------------OC only---------------------
#block开始的正则
MacroBlockBegin: ''
#block开始的正则
MacroBlockEnd: ''
#在block从空行开始
KeepEmptyLinesAtTheStartOfBlocks: true
#block内的缩进
ObjCBlockIndentWidth: 4
#是否需要在"@property"后加上空格
ObjCSpaceAfterProperty: true
#是否需要在协议名后加上空格
ObjCSpaceBeforeProtocolList: true
#----------------------------other-------------------
#AlwaysBreakAfterDefinitionReturnType
#AlwaysBreakAfterReturnType
#AlwaysBreakBeforeMultilineStrings: false
#AlwaysBreakTemplateDeclarations: false
#PenaltyReturnTypeOnItsOwnLine: 20
#PointerBindsToType: 100
#SpacesInCStyleCastParentheses: false
第二个问题 其实也很简单,CLangFormat就是把clang-format进行了wrap,clang-format本身其实是一个命令行工具,所以嘛,写个shell脚本就能把以前代码都格式化了。具体的命令如下:
find . -regex “.*.[hm]” | xargs clang-format -i -style=file
把上面的命令解释下,这行命令分为3部分:
1 find . -regex ".*\.[hm]"
是找出当前目录所在的所有以h和m结尾的文件
2 | xargs
把文件导入到xargs中,逐个调用clang-format命令
3 clang-format -i -style=file
这里就是对文件进行格式化了,-i
的意思是把格式化好的代码直接写入源文件,-sytle=file
指从当前目录或者当前父目录搜索文件名为.clang-format的格式配置文件
当然,这行命令需要你根据你自己的clang-format的路径做一下调整。