让你的代码自动格式化
前言
每个团队都应该有统一的代码风格和规范,这带来的好处我相信不言而喻,具体我就不多说了,大家都懂的。如何更有效率的去做这件事呢,我这次就来说说如何更好的自动格式化你的代码。
现状
大多数 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主页查看。
总结
这是我第一次在上写文章(别的地方也没写过多少),写的不好,大家海涵呐,多多提意见哈。