使用clang-format對(duì)iOS項(xiàng)目代碼進(jìn)行格式化
公司的項(xiàng)目已經(jīng)迭代了近兩年,在兩年的時(shí)間里不斷的有新人參加到項(xiàng)目里菠隆,每個(gè)人都有自己的代碼風(fēng)格,隨著項(xiàng)目越來(lái)越大,沒(méi)有統(tǒng)一代碼規(guī)范帶來(lái)的維護(hù)問(wèn)題也越來(lái)越多宾舅,所以和小組的同事商量了下制定了iOS的編碼規(guī)范敬尺。
規(guī)范總是要執(zhí)行才能生效,不過(guò)幾千字的編碼規(guī)范總不能每次寫代碼前都熟讀一遍吧贴浙,翻了下Package Manager砂吞,發(fā)現(xiàn)CLangFormat可以根據(jù)代碼規(guī)范格式化代碼。具體的使用方式已經(jīng)有大神非常詳盡地介紹崎溃,感興趣的同學(xué)請(qǐng)移步《iOS 代碼格式化管理》—Bannings的專欄蜻直。
看了《iOS 代碼格式化管理》后發(fā)現(xiàn)我們當(dāng)前還需要解決兩個(gè)問(wèn)題:一個(gè)是自定義符合我們團(tuán)隊(duì)的代碼規(guī)范;另外一個(gè)是根據(jù)規(guī)范整理以前寫的代碼袁串。
第一個(gè)問(wèn)題 在《iOS 代碼格式化管理》中已經(jīng)介紹過(guò)概而,主要是配置.clang-format文件,讓CLangFormat根據(jù)自定義的配置格式化代碼囱修,這里貼出我們團(tuán)隊(duì)使用的.clang-format配置赎瑰。因?yàn)?clang-format的配置選項(xiàng)非常多、有些選項(xiàng)的解釋非常模糊破镰,所以我們只測(cè)試了常用的選項(xiàng)餐曼,沒(méi)用到的都注釋了。
$ cd /Users/xxxx/AppGo
$ vim .clang-fomat
$ open .clang-fomat
禁用當(dāng)前format文件
DisableFormat: false
BasedOnStyle: WebKit
是否使用tab進(jìn)行縮進(jìn)
UseTab: Never
TabWidth: 4
IndentWidth: 4
語(yǔ)言
Language: Cpp
Standard: Cpp11
includeCategoriesStandard: Cpp11
Cpp11BracedListStyle: false
ForEachMacros
IncludeCategories
-----------------------file----------------------
最大寬度,如果代碼超過(guò)這個(gè)寬度會(huì)按語(yǔ)義折行
ColumnLimit: 130
最多能超出ColumnLimit多少個(gè)字符
PenaltyExcessCharacter: 0
允許最大連續(xù)空行數(shù)
MaxEmptyLinesToKeep: 10
在續(xù)行(\
下一行)時(shí)的縮進(jìn)長(zhǎng)度
ContinuationIndentWidth: 4
CommentPragmas: ''
DerivePointerBinding: false
--------------------------code block------------------
括號(hào)的斷行模式
BreakBeforeBraces: Mozilla
是否在容器字面量(@[@"1",@"2"])中插入空格
SpacesInContainerLiterals: true
case語(yǔ)句的位置總是在switch語(yǔ)句后縮進(jìn)一級(jí)
IndentCaseLabels: true
多行賦值語(yǔ)句按=號(hào)對(duì)齊
AlignConsecutiveAssignments: false
多行聲明語(yǔ)句按=號(hào)對(duì)齊
AlignConsecutiveDeclarations: false
是否把注釋右對(duì)齊,下面為右對(duì)齊的效果
void someFunction() {
doWork(); // Does something
doMoreWork(); // Does something else
}
AlignTrailingComments: true
是否在括號(hào)前加上空格
SpaceBeforeParens: ControlStatements
在未封閉(括號(hào)的開(kāi)始和結(jié)束不在同一行)的括號(hào)中的代碼是否對(duì)齊
if(a &&
b)
AlignAfterOpenBracket: Align
類的訪問(wèn)修飾關(guān)鍵字(private,public,protected···)縮進(jìn)
private:
int a;
1表示不縮進(jìn)
大于1的值表示訪問(wèn)修飾關(guān)鍵字的左側(cè)從int a的左側(cè)列開(kāi)始往右側(cè)移動(dòng)的距離
AccessModifierOffset: 1
在構(gòu)造函數(shù)初始化時(shí)按逗號(hào)斷行鲜漩,并以冒號(hào)對(duì)齊
BreakConstructorInitializersBeforeComma: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 0
ExperimentalAutoDetectBinPacking: false
IndentWrappedFunctionNames: true
IndentFunctionDeclarationAfterType: false
AlignEscapedNewlinesLeft: true
BinPackArguments: false
BinPackParameters: false
AllowAllParametersOfDeclarationOnNextLine: false
----------------------sataement----------------
指針在類型那邊還是在變量名那邊還是在中間
PointerAlignment: Right
在=號(hào)前加空格
SpaceBeforeAssignmentOperators: true
是否在空括號(hào)中加空格
SpaceInEmptyParentheses: false
單行注釋前的空格數(shù)
SpacesBeforeTrailingComments: 0
是否在<>中間插入空格
SpacesInAngles: false
是否在非空的括號(hào)中插入空格
SpacesInParentheses: false
在三元運(yùn)算符前斷行
BreakBeforeTernaryOperators: true
在二元運(yùn)算符前斷行
BreakBeforeBinaryOperators: All
是否允許短代碼塊在一行寫完
如 if (a) { return; }
AllowShortBlocksOnASingleLine: false
是否允許短switch的case 語(yǔ)句在一行寫完
AllowShortCaseLabelsOnASingleLine: true
是否允許短的函數(shù)在一行寫完
AllowShortFunctionsOnASingleLine: false
是否允許短的語(yǔ)句在一行寫完
AllowShortIfStatementsOnASingleLine: true
是否允許短的循環(huán)在一行寫完
AllowShortLoopsOnASingleLine: true
命名空間縮進(jìn)
NamespaceIndentation: All
AlignOperands: false
PenaltyBreakBeforeFirstCallParameter: 100
PenaltyBreakComment: 100
PenaltyBreakFirstLessLess: 0
PenaltyBreakString: 100
-----------------------------OC only---------------------
block開(kāi)始的正則
MacroBlockBegin: ''
block開(kāi)始的正則
MacroBlockEnd: ''
在block從空行開(kāi)始
KeepEmptyLinesAtTheStartOfBlocks: true
block內(nèi)的縮進(jìn)
ObjCBlockIndentWidth: 4
是否需要在"@property"后加上空格
ObjCSpaceAfterProperty: true
是否需要在協(xié)議名后加上空格
ObjCSpaceBeforeProtocolList: true
----------------------------other-------------------
AlwaysBreakAfterDefinitionReturnType
AlwaysBreakAfterReturnType
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
PenaltyReturnTypeOnItsOwnLine: 20
PointerBindsToType: 100
SpacesInCStyleCastParentheses: false
第二個(gè)問(wèn)題 其實(shí)也很簡(jiǎn)單源譬,CLangFormat就是把clang-format進(jìn)行了wrap,clang-format本身其實(shí)是一個(gè)命令行工具孕似,所以嘛踩娘,寫個(gè)shell腳本就能把以前代碼都格式化了。具體的命令如下:
find . -regex “..[hm]” | xargs clang-format -i -style=file
把上面的命令解釋下喉祭,這行命令分為3部分:
1 find . -regex "..[hm]"是找出當(dāng)前目錄所在的所有以h和m結(jié)尾的文件
2 | xargs把文件導(dǎo)入到xargs中养渴,逐個(gè)調(diào)用clang-format命令
3 clang-format -i -style=file 這里就是對(duì)文件進(jìn)行格式化了,-i的意思是把格式化好的代碼直接寫入源文件泛烙,-sytle=file指從當(dāng)前目錄或者當(dāng)前父目錄搜索文件名為.clang-format的格式配置文件
當(dāng)然理卑,這行命令需要你根據(jù)你自己的clang-format的路徑做一下調(diào)整。