前言
每個團隊都應該有統一的程式碼風格和規範,這帶來的好處我相信不言而喻,具體我就不多說了,大家都懂的?。如何更有效率的去做這件事呢,我這次就來說說如何更好的自動格式化你的程式碼。
現狀
大多數 iOS 開發者應該都知道 Xcode 的外掛 Clang Format,它是基於 clang-format 命令列工具的一個 Xcode 外掛,但是這款外掛在Xcode9上已經無法使用了,因為Xcode9的外掛機制已經變了。
現在可以使用這一款XcodeClangFormat,具體的使用方式點選連結,大家自行去看吧。這款有個缺點,就是不能像之前那款外掛可以設定在儲存時自動格式化(這其實也不能怪作者,Xcode新的機制不允許)。
不過使用這種外掛還是不夠方便,你還得手動選中檔案或者程式碼再按快捷鍵來格式化,很容易忘,而導致把不規範的程式碼直接提交到倉庫裡了。
那麼有沒有一種方式,可以讓我在敲程式碼的時候隨心所欲,提交時又能提醒我然後自動幫我格式化嗎?
該怎麼做
這裡我直接介紹一款神器Space Commander,它利用 Git Hooks ,在 commit 之前檢查程式碼風格是否符合規範,只有符合規範的程式碼才允許提交,列出不符合規範的檔案,同時提供 Shell 指令碼來自動格式化。接下來我介紹下如何使用。
- 1 clone Space Commander
git clone https://github.com/square/spacecommander.git
- 2 在專案中安裝Space Commander
cd到你的專案根目錄,執行setup-repo.sh指令碼(在你clone下來的專案中,所以要全路徑),執行完後會在專案根目錄多一個隱藏檔案.clang-format,這是一個替身,指向Space Commander倉庫中的.clang-format檔案,裡面預設包含了一系列程式碼規則,如果你想要用自己的規則,可以去Space Commander倉庫中改真身,也可以用新的.clang-format檔案替換掉這個替身。 - 3 讓我們提交程式碼試試
BasedOnStyle: Chromium
IndentWidth: 4
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
ObjCSpaceAfterProperty: true
PointerAlignment: Right
BreakBeforeBraces: Attach
這是我自定義的一些規則,具體.clang-format的寫法請參照這個。
好,讓我們寫一下程式碼
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic, copy) NSString* p;
@property(nonatomic, strong) UITextView * textview;
@end
@implementation ViewController
-(void)formatTest:(NSString *)param{
if (param) {
NSLog(@"sss");
}
int a=0;
int b = 1;
int c= 2;
NSLog(@"%d%d%d",a,b,c);
}
-(void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewDidAppear:(BOOL)animated {
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
複製程式碼
這一看,就很不規範吧,先讓我們提交看看
提交的時候明確提示ViewController檔案需要格式化,這時候我們可以使用format-objc-file.sh指令碼單獨格式化某個檔案,也可以format-objc-files.sh格式化所有的暫存檔案,甚至使用format-objc-files-in-repo.sh格式化整個倉庫的檔案。 再提交一遍 好,接下來我們在看看程式碼變成什麼樣子了#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, copy) NSString * p;
@property (nonatomic, strong) UITextView *textview;
@end
@implementation ViewController
- (void)formatTest:(NSString *)param {
if (param) {
NSLog(@"sss");
}
int a = 0;
int b = 1;
int c = 2;
NSLog(@"%d%d%d", a, b, c);
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidAppear:(BOOL)animated {
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
複製程式碼
完美!?
後續
可以看到上面的命令太長了,必須要指定shell指令碼的全路徑才能執行,我們可以簡化命令,如果你用的zsh,去修改 ~/.zshrc,如果是bash,則修改~/.bash_profile,
// 初始化
alias clangformatsetup="/你自己的路徑/spacecommander/setup-repo.sh"
// 格式化對應檔案
alias clangformatfile="/你自己的路徑/spacecommander/format-objc-file.sh"
// 格式化所有暫存檔案
alias clangformatfiles="/你自己的路徑/spacecommander/format-objc-files.sh"
// 格式化整個倉庫
alias clangformatall="/你自己的路徑/spacecommander/format-objc-files-in-repo.sh
複製程式碼
如果你還想知道更多的用法,直接去spacecommander的github主頁檢視。
總結
這是我第一次在掘金上寫文章(別的地方也沒寫過多少?),寫的不好,大家海涵吶,多多提意見哈?。