├── .DS_Store ├── .gitignore ├── GHWExtension ├── GHWExtension.entitlements ├── GHWExtensionConst.h ├── Info.plist ├── SourceEditorCommand.h ├── SourceEditorCommand.m ├── SourceEditorExtension.h ├── SourceEditorExtension.m ├── Tools │ ├── NSMutableArray+GHWExtension.h │ ├── NSMutableArray+GHWExtension.m │ ├── NSString+Extension.h │ └── NSString+Extension.m ├── addComment │ ├── GHWAddCommentManager.h │ └── GHWAddCommentManager.m ├── addImport │ ├── GHWAddImportManager.h │ └── GHWAddImportManager.m ├── addLazyCode │ ├── GHWAddLazyCodeManager.h │ └── GHWAddLazyCodeManager.m ├── initView │ ├── GHWInitViewManager.h │ └── GHWInitViewManager.m └── sortImport │ ├── GHWSortImportManager.h │ └── GHWSortImportManager.m ├── GHWXcodeExtension.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ ├── GHWExtension.xcscheme │ │ └── GHWXcodeExtension.xcscheme └── xcuserdata │ └── guohongwei719.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── GHWXcodeExtension ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon-2.appiconset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── GHWXcodeExtension.entitlements ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── README.md └── resources ├── 01.png ├── 010.png ├── 011.png ├── 02.png ├── 03.png ├── 04.png ├── 05.png ├── 06.png ├── 07.png ├── 08.png ├── 09.png ├── 0addImport.gif ├── 0addLazyCode.gif ├── 0initView.gif └── 0sortImport.gif /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots/**/*.png 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject/ 64 | 65 | -------------------------------------------------------------------------------- /GHWExtension/GHWExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GHWExtension/GHWExtensionConst.h: -------------------------------------------------------------------------------- 1 | // 2 | // GHWExtensionConst.h 3 | // 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019年 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "NSString+Extension.h" 10 | #import "NSMutableArray+GHWExtension.h" 11 | 12 | 13 | /*************************************************************************/ 14 | 15 | static NSString *const kUIButton = @"UIButton"; 16 | static NSString *const kUILabel = @"UILabel"; 17 | static NSString *const kUIScrollView = @"UIScrollView"; 18 | static NSString *const kUITableView = @"UITableView"; 19 | static NSString *const kUICollectionView = @"UICollectionView"; 20 | static NSString *const kUIImageView = @"UIImageView"; 21 | static NSString *const kImplementation = @"@implementation"; 22 | static NSString *const kInterface = @"@interface"; 23 | static NSString *const kEnd = @"@end"; 24 | static NSString *const kGetterSetterPragmaMark = @"#pragma mark - Setter / Getter"; 25 | 26 | 27 | /******************************* addComment ******************************************/ 28 | static NSString * const kAddCommentExtensionCode = @"/**\n *\n *\n *\n *\n *\n *\n *\n *\n */"; 29 | static NSString * const kAddCommentHeaderExtensionCode = @"/**\n * Description\n *"; 30 | static NSString * const kAddCommentFooterExtensionCode = @" *\n * @return return value description\n */"; 31 | static NSString * const kAddCommentFooterNoParamsExtensionCode = @" * @return return value description\n */"; 32 | 33 | /******************************* initView ******************************************/ 34 | static NSString * const kInitViewExtensionCode = @"@interface %@ ()\n\n\n\n@end\n"; 35 | static NSString * const kInitViewLifeCycleCode = @"\n- (instancetype)initWithFrame:(CGRect)frame {\n self = [super initWithFrame:frame];\n if (self) {\n [self configViews];\n }\n return self;\n}\n\n- (void)configViews {\n\n}\n\n#pragma mark - Public Methods\n\n#pragma mark - Private Methods\n\n#pragma mark - Setter / Getter"; 36 | 37 | static NSString * const kInitTableViewCellLifeCycleCode = @"\n- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];\n if (self) {\n [self configViews];\n }\n return self;\n}\n\n- (void)configViews {\n self.selectionStyle = UITableViewCellSelectionStyleNone;\n}\n\n- (void)configWithData {\n\n\n}"; 38 | 39 | static NSString * const kInitViewControllerLifeCycleCode = @"\n#pragma mark - Life Cycle\n\n- (void)viewDidLoad {\n [super viewDidLoad];\n [self configViews];\n [self configData];\n}\n\n- (void)viewWillAppear:(BOOL)animated {\n [super viewWillAppear:animated];\n\n}\n\n#pragma mark - Setup View / Data\n\n- (void)configViews {\n\n}\n\n- (void)configData {\n\n}\n\n#pragma mark - Observer\n\n#pragma mark - Notification\n\n#pragma mark - Event Response\n\n#pragma mark - Override Methods\n\n#pragma mark - Delegate\n\n#pragma mark - Public Methods\n\n#pragma mark - Private Methods\n\n#pragma mark - Setter / Getter\n\n#pragma mark - Network"; 40 | 41 | /******************************* addlazyCode ******************************************/ 42 | //自定义内容格式 43 | 44 | 45 | static NSString * const kAddLazyCodeTableViewDataSourceAndDelegate = @"\n#pragma mark - tableView DataSource\n\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {\n return 5;\n}\n\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {\n UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@\"UITableViewCell\"];\n if (indexPath.row % 2 == 0) {\n cell.contentView.backgroundColor = [UIColor blueColor];\n } else {\n cell.contentView.backgroundColor = [UIColor redColor];\n }\n return cell;\n}\n\n#pragma mark - tableView Delegate\n\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {\n return 60;\n}\n\n-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {\n\n}"; 46 | 47 | static NSString * const kAddLazyCodeUICollectionViewDelegate = @"#pragma mark - UICollectionViewDataSource\n\n- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {\n return 0;\n}\n\n- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {\n UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@\"UICollectionViewCell\" forIndexPath:indexPath];\n return cell;\n}\n\n#pragma mark - UICollectionViewDelegate\n\n- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {\n\n}"; 48 | 49 | static NSString * const kAddLazyCodeUIScrollViewDelegate = @"#pragma mark - UIScrollviewDelegate\n\n- (void)scrollViewDidScroll:(UIScrollView *)scrollView {\n\n\n}"; 50 | 51 | //static NSString * const kLazyImageViewCode = @"- (%@ *)%@ {\n if (!_%@) {\n _%@ = [[%@ alloc] initWithImage:ni”; 52 | // 53 | //static NSString * const kLazyScrollViewCode = @"- (%@ *)%@ {\n if (!_%@) {\n _%@ = [[%@ alloc] init];\n _%@.alwaysBounceVertical = YE"; 54 | 55 | static NSString *const kLazyCommonCode = @"\n- (%@ *)%@ {\n if (!_%@) {\n _%@ = [[%@ alloc] init];\n }\n return _%@;\n}"; 56 | 57 | 58 | static NSString * const kLazyImageViewCode = @"- (%@ *)%@ {\n if (!_%@) {\n _%@ = [[%@ alloc] initWithImage:nil];\n _%@.contentMode = UIViewContentModeScaleAspectFill;\n _%@.clipsToBounds = YES;\n }\n return _%@;\n}"; 59 | 60 | static NSString *const kLazyLabelCode = @"- (%@ *)%@ {\n if (!_%@) {\n _%@ = [[%@ alloc] initWithFrame:CGRectZero];\n _%@.textAlignment = NSTextAlignmentLeft;\n _%@.textColor = [UIColor blackColor];\n _%@.font = [UIFont systemFontOfSize:18];\n _%@.text = @\"test\";\n }\n return _%@;\n}"; 61 | 62 | static NSString *const kLazyButtonCode = @"- (%@ *)%@ {\n if (!_%@) {\n _%@ = [%@ buttonWithType:UIButtonTypeCustom];\n [_%@ setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];\n _%@.titleLabel.font = [UIFont systemFontOfSize:14];\n [_%@ setTitle:@\"test\" forState:UIControlStateNormal];\n [_%@ addTarget:self action:@selector(buttonTap:) forControlEvents:UIControlEventTouchUpInside];\n }\n return _%@;\n}"; 63 | 64 | static NSString * const kLazyScrollViewCode = @"- (%@ *)%@ {\n if (!_%@) {\n _%@ = [[%@ alloc] init];\n _%@.alwaysBounceVertical = YES;\n _%@.backgroundColor = [UIColor lightGrayColor];\n _%@.delegate = self;\n }\n return _%@;\n}\n"; 65 | 66 | static NSString * const kLazyUITableViewCode = @"- (%@ *)%@ {\n if (!_%@) {\n _%@ = [[%@ alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];\n _%@.delegate = self;\n _%@.dataSource = self;\n _%@.backgroundColor = [UIColor whiteColor];\n _%@.separatorStyle = UITableViewCellSeparatorStyleNone;\n if (@available(iOS 11.0, *)) {\n _%@.estimatedRowHeight = 0;\n _%@.estimatedSectionFooterHeight = 0;\n _%@.estimatedSectionHeaderHeight = 0;\n _%@.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;\n }\n [_%@ registerClass:[UITableViewCell class] forCellReuseIdentifier:@\"UITableViewCell\"];\n }\n return _%@;\n}\n"; 67 | 68 | static NSString * const kLazyUICollectionViewCode = @"- (%@ *)%@ {\n if (!_%@) {\n UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];\n layout.itemSize = CGSizeMake(10, 10);\n layout.minimumLineSpacing = 0;\n layout.minimumInteritemSpacing = 0;\n layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;\n\n _%@ = [[%@ alloc] initWithFrame:CGRectZero collectionViewLayout:layout];\n _%@.dataSource = self;\n _%@.delegate = self;\n [_%@ registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@\"UICollectionViewCell\"];\n }\n return _%@;\n}"; 69 | -------------------------------------------------------------------------------- /GHWExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | GHWExtension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | XCSourceEditorCommandDefinitions 30 | 31 | 32 | XCSourceEditorCommandClassName 33 | SourceEditorCommand 34 | XCSourceEditorCommandIdentifier 35 | $(PRODUCT_BUNDLE_IDENTIFIER).SourceEditorCommand 36 | XCSourceEditorCommandName 37 | Source Editor Command 38 | 39 | 40 | XCSourceEditorExtensionPrincipalClass 41 | SourceEditorExtension 42 | 43 | NSExtensionPointIdentifier 44 | com.apple.dt.Xcode.extension.source-editor 45 | 46 | NSHumanReadableCopyright 47 | Copyright © 2019 黑化肥发灰. All rights reserved. 48 | 49 | 50 | -------------------------------------------------------------------------------- /GHWExtension/SourceEditorCommand.h: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorCommand.h 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/29. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SourceEditorCommand : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /GHWExtension/SourceEditorCommand.m: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorCommand.m 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/29. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "SourceEditorCommand.h" 10 | #import "GHWInitViewManager.h" 11 | #import "GHWAddLazyCodeManager.h" 12 | #import "GHWSortImportManager.h" 13 | #import "GHWAddImportManager.h" 14 | 15 | @implementation SourceEditorCommand 16 | 17 | - (void)performCommandWithInvocation:(XCSourceEditorCommandInvocation *)invocation 18 | completionHandler:(void (^)(NSError * _Nullable nilOrError))completionHandler 19 | { 20 | // Implement your command here, invoking the completion handler when done. Pass it nil on success, and an NSError on failure. 21 | NSString *identifier = invocation.commandIdentifier; 22 | [invocation.buffer.lines enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 23 | NSLog(@"%@", obj); 24 | }]; 25 | if ([identifier hasPrefix:@"com.jingyao.GHWXcodeExtension.GHWExtension.sortImport"]) { 26 | [[GHWSortImportManager sharedInstane] processCodeWithInvocation:invocation]; 27 | } else if ([identifier hasPrefix:@"com.jingyao.GHWXcodeExtension.GHWExtension.initView"]) { 28 | [[GHWInitViewManager sharedInstane] processCodeWithInvocation:invocation]; 29 | } else if ([identifier hasPrefix:@"com.jingyao.GHWXcodeExtension.GHWExtension.addLazyCode"]) { 30 | [[GHWAddLazyCodeManager sharedInstane] processCodeWithInvocation:invocation]; 31 | } else if ([identifier hasPrefix:@"com.jingyao.GHWXcodeExtension.GHWExtension.addImport"]) { 32 | [[GHWAddImportManager sharedInstane] processCodeWithInvocation:invocation]; 33 | } 34 | completionHandler(nil); 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /GHWExtension/SourceEditorExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorExtension.h 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/29. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SourceEditorExtension : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /GHWExtension/SourceEditorExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorExtension.m 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/29. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "SourceEditorExtension.h" 10 | 11 | @implementation SourceEditorExtension 12 | 13 | /* 14 | - (void)extensionDidFinishLaunching 15 | { 16 | // If your extension needs to do any work at launch, implement this optional method. 17 | } 18 | */ 19 | 20 | 21 | - (NSArray *> *)commandDefinitions 22 | { 23 | // If your extension needs to return a collection of command definitions that differs from those in its Info.plist, implement this optional property getter. 24 | 25 | 26 | return @[@{XCSourceEditorCommandClassNameKey: @"SourceEditorCommand", 27 | XCSourceEditorCommandIdentifierKey: @"com.jingyao.GHWXcodeExtension.GHWExtension.initView", 28 | XCSourceEditorCommandNameKey: @"initView" 29 | }, 30 | @{XCSourceEditorCommandClassNameKey: @"SourceEditorCommand", 31 | XCSourceEditorCommandIdentifierKey: @"com.jingyao.GHWXcodeExtension.GHWExtension.addLazyCode", 32 | XCSourceEditorCommandNameKey: @"addLazyCode" 33 | }, 34 | @{XCSourceEditorCommandClassNameKey: @"SourceEditorCommand", 35 | XCSourceEditorCommandIdentifierKey: @"com.jingyao.GHWXcodeExtension.GHWExtension.addImport", 36 | XCSourceEditorCommandNameKey: @"addImport" 37 | }, 38 | @{XCSourceEditorCommandClassNameKey: @"SourceEditorCommand", 39 | XCSourceEditorCommandIdentifierKey: @"com.jingyao.GHWXcodeExtension.GHWExtension.sortImport", 40 | XCSourceEditorCommandNameKey: @"sortImport" 41 | }]; 42 | } 43 | 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /GHWExtension/Tools/NSMutableArray+GHWExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+GHWExtension.h 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSMutableArray (GHWExtension) 14 | 15 | - (NSInteger)indexOfFirstItemContainStrsArray:(NSArray *)strsArray; 16 | - (NSInteger)indexOfFirstItemContainStr:(NSString *)str; 17 | - (NSInteger)indexOfFirstItemContainStr:(NSString *)str fromIndex:(NSInteger)fromIndex; 18 | - (NSInteger)indexOfFirstItemContainStr:(NSString *)str fromIndex:(NSInteger)fromIndex andToIndex:(NSInteger)toIndex; 19 | - (void)insertItemsOfArray:(NSArray *)itemsArray fromIndex:(NSInteger)insertIndex; 20 | - (NSString *)fetchClassName; 21 | - (NSString *)fetchCurrentClassNameWithCurrentIndex:(NSInteger)currentIndex; 22 | - (void)deleteItemsFromFirstItemContains:(NSString *)firstStr andLastItemsContainsStr:(NSString *)lastStr; 23 | - (void)printList; 24 | - (NSMutableArray *)arrayWithNoSameItem; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /GHWExtension/Tools/NSMutableArray+GHWExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+GHWExtension.m 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "NSMutableArray+GHWExtension.h" 10 | #import "NSString+Extension.h" 11 | #import "GHWExtensionConst.h" 12 | 13 | @implementation NSMutableArray (GHWExtension) 14 | 15 | - (NSInteger)indexOfFirstItemContainStr:(NSString *)str { 16 | str = [str deleteSpaceAndNewLine]; 17 | NSInteger index = NSNotFound; 18 | for (int i = 0; i < self.count; i++) { 19 | NSString *contentStr = [[self objectAtIndex:i] deleteSpaceAndNewLine]; 20 | NSRange range = [contentStr rangeOfString:str]; 21 | if (range.location != NSNotFound) { 22 | index = i; 23 | break; 24 | } 25 | } 26 | return index; 27 | } 28 | 29 | - (NSInteger)indexOfFirstItemContainStrsArray:(NSArray *)strsArray { 30 | NSInteger index = NSNotFound; 31 | for (int i = 0; i < self.count; i++) { 32 | NSString *contentStr = [[self objectAtIndex:i] deleteSpaceAndNewLine]; 33 | BOOL isOk = YES; 34 | for (int j = 0; j < [strsArray count]; j++) { 35 | NSString *tempStr = strsArray[j]; 36 | if (![contentStr containsString:tempStr]) { 37 | isOk = NO; 38 | } 39 | } 40 | 41 | if (isOk) { 42 | index = i; 43 | break; 44 | } 45 | 46 | } 47 | return index; 48 | } 49 | 50 | - (NSInteger)indexOfFirstItemContainStr:(NSString *)str fromIndex:(NSInteger)fromIndex { 51 | str = [str deleteSpaceAndNewLine]; 52 | NSInteger index = NSNotFound; 53 | for (NSInteger i = fromIndex; i < self.count; i++) { 54 | NSString *contentStr = [[self objectAtIndex:i] deleteSpaceAndNewLine]; 55 | NSRange range = [contentStr rangeOfString:str]; 56 | if (range.location != NSNotFound) { 57 | index = i; 58 | break; 59 | } 60 | } 61 | return index; 62 | } 63 | 64 | - (NSInteger)indexOfFirstItemContainStr:(NSString *)str fromIndex:(NSInteger)fromIndex andToIndex:(NSInteger)toIndex { 65 | str = [str deleteSpaceAndNewLine]; 66 | NSInteger index = NSNotFound; 67 | for (NSInteger i = fromIndex; i <= toIndex; i++) { 68 | NSString *contentStr = [[self objectAtIndex:i] deleteSpaceAndNewLine]; 69 | NSRange range = [contentStr rangeOfString:str]; 70 | if (range.location != NSNotFound) { 71 | index = i; 72 | break; 73 | } 74 | } 75 | return index; 76 | } 77 | 78 | - (void)insertItemsOfArray:(NSArray *)itemsArray fromIndex:(NSInteger)insertIndex { 79 | for (int i = 0; i < [itemsArray count]; i++) { 80 | NSString *str = itemsArray[i]; 81 | [self insertObject:str atIndex:insertIndex]; 82 | insertIndex = insertIndex + 1; 83 | } 84 | } 85 | 86 | // 注释里面的类名字 87 | - (NSString *)fetchReferenceClassName { 88 | NSString *className = nil; 89 | NSRange range; 90 | NSString *str0 = [self[1] deleteSpaceAndNewLine]; 91 | if ([str0 hasPrefix:@"//"] && [str0 hasSuffix:@".m"]) { 92 | if ([str0 containsString:@"+"]) { 93 | range = [str0 rangeOfString:@"+"]; 94 | } else { 95 | range = [str0 rangeOfString:@"."]; 96 | } 97 | className = [str0 substringWithRange:NSMakeRange(2, range.location - 2)]; 98 | } 99 | return className; 100 | } 101 | 102 | 103 | // 本文件类名 104 | - (NSString *)fetchClassName { 105 | NSString *referenceClassName = [self fetchReferenceClassName]; 106 | NSString *className = @""; 107 | for (int i = 0; i < [self count]; i++) { 108 | NSString *tempStr = [self[i] deleteSpaceAndNewLine]; 109 | if ([tempStr hasPrefix:kImplementation]) { 110 | if ([tempStr containsString:@"("]) { 111 | className = [tempStr stringBetweenLeftStr:kImplementation andRightStr:@"("]; 112 | } else { 113 | className = [tempStr substringFromIndex:[kImplementation length]]; 114 | } 115 | } else if ([tempStr hasPrefix:kInterface]) { 116 | if ([tempStr containsString:@":"]) { 117 | className = [tempStr stringBetweenLeftStr:kInterface andRightStr:@":"]; 118 | 119 | } else if ([tempStr containsString:@"("]) { 120 | className = [tempStr stringBetweenLeftStr:kInterface andRightStr:@"("]; 121 | 122 | } 123 | } 124 | if (referenceClassName && [referenceClassName isEqualToString:className]) { 125 | return referenceClassName; 126 | } 127 | } 128 | return className; 129 | } 130 | 131 | - (NSString *)fetchCurrentClassNameWithCurrentIndex:(NSInteger)currentIndex { 132 | NSString *className = nil; 133 | for (NSInteger i = currentIndex; i >= 0; i--) { 134 | NSString *tempStr = [self[i] deleteSpaceAndNewLine]; 135 | if ([tempStr hasPrefix:kImplementation]) { 136 | if ([tempStr containsString:@"("]) { 137 | className = [tempStr stringBetweenLeftStr:kImplementation andRightStr:@"("]; 138 | } else { 139 | className = [tempStr substringFromIndex:[kImplementation length]]; 140 | } 141 | break; 142 | } else if ([tempStr hasPrefix:kInterface]) { 143 | if ([tempStr containsString:@":"]) { 144 | className = [tempStr stringBetweenLeftStr:kInterface andRightStr:@":"]; 145 | 146 | } else if ([tempStr containsString:@"("]) { 147 | className = [tempStr stringBetweenLeftStr:kInterface andRightStr:@"("]; 148 | 149 | } 150 | break; 151 | } 152 | } 153 | return className; 154 | } 155 | 156 | - (void)deleteItemsFromFirstItemContains:(NSString *)firstStr andLastItemsContainsStr:(NSString *)lastStr { 157 | NSInteger deleteFirstLine = 0; 158 | NSInteger deleteLastLine = 0; 159 | for (int i = 0; i < [self count]; i++) { 160 | NSString *tempStr = self[i]; 161 | tempStr = [tempStr deleteSpaceAndNewLine]; 162 | if ([tempStr hasPrefix:@"/*"]) { 163 | deleteFirstLine = i; 164 | } else if ([tempStr hasPrefix:@"*/"]) { 165 | deleteLastLine = i; 166 | } 167 | } 168 | if (deleteLastLine != deleteFirstLine) { 169 | [self removeObjectsInRange:NSMakeRange(deleteFirstLine, deleteLastLine - deleteFirstLine + 1)]; 170 | } 171 | } 172 | 173 | - (void)printList { 174 | for (NSInteger i = 0; i < [self count]; i++) { 175 | NSLog(@"%@", self[i]); 176 | } 177 | } 178 | 179 | - (NSMutableArray *)arrayWithNoSameItem { 180 | NSSet *set = [NSSet setWithArray:self]; 181 | return [NSMutableArray arrayWithArray:[set allObjects]]; 182 | } 183 | 184 | @end 185 | -------------------------------------------------------------------------------- /GHWExtension/Tools/NSString+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Extension.h 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019年 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | 12 | @interface NSString (Extension) 13 | 14 | 15 | /* 16 | * 返回中间字符串 17 | * 如果 leftStr 为 nil , 则返回 rightStr 之前的字符串 18 | */ 19 | - (NSString *)stringBetweenLeftStr:(NSString *)leftStr andRightStr:(NSString *)rightStr; 20 | 21 | // 删除空格和换行符 22 | - (NSString *)deleteSpaceAndNewLine; 23 | 24 | // 获取类型字符串 25 | - (NSString *)fetchClassNameStr; 26 | 27 | // 获取属性名 28 | - (NSString *)fetchPropertyNameStr; 29 | 30 | - (BOOL)checkHasContainsOneOfStrs:(NSArray *)strArray andNotContainsOneOfStrs:(NSArray *)noHasStrsArray; 31 | @end 32 | -------------------------------------------------------------------------------- /GHWExtension/Tools/NSString+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Extension.m 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019年 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "NSString+Extension.h" 10 | 11 | @implementation NSString (Extension) 12 | 13 | - (NSString *)stringBetweenLeftStr:(NSString *)leftStr andRightStr:(NSString *)rightStr { 14 | NSString *str = @""; 15 | NSArray *arr = [NSArray array]; 16 | if (!leftStr) { 17 | arr = [self componentsSeparatedByString:rightStr]; 18 | if (arr.count > 0) { 19 | str = arr.firstObject; 20 | } 21 | } else { 22 | arr = [self componentsSeparatedByString:leftStr]; 23 | if (arr.count > 1) { 24 | NSArray * subArr = [arr.lastObject componentsSeparatedByString:rightStr]; 25 | if (subArr.count > 0) { 26 | str = subArr.firstObject; 27 | if ([str containsString:@"_"]) { 28 | str = [str stringByReplacingOccurrencesOfString:@"_" withString:@""]; 29 | } 30 | } 31 | } 32 | } 33 | return [str deleteSpaceAndNewLine]; 34 | } 35 | 36 | - (NSString *)deleteSpaceAndNewLine { 37 | NSString *str = [self stringByReplacingOccurrencesOfString:@" " withString:@""]; 38 | str = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 39 | return str; 40 | } 41 | 42 | - (NSString *)fetchClassNameStr { 43 | NSString *tempStr = [self deleteSpaceAndNewLine]; 44 | NSString *classNameStr = nil; 45 | if ([tempStr containsString:@"*"]) { 46 | //判断NSMutableArray *testArray 这样的情况来处理 47 | if ([tempStr containsString:@"NSMutableArray<"]) { 48 | classNameStr = [tempStr stringBetweenLeftStr:@")" andRightStr:@"*>"]; 49 | classNameStr = [classNameStr stringByAppendingString:@"*>"]; 50 | } else if ([tempStr containsString:@")"]) { 51 | classNameStr = [tempStr stringBetweenLeftStr:@")" andRightStr:@"*"]; 52 | } else { 53 | classNameStr = [tempStr stringBetweenLeftStr:nil andRightStr:@"*"]; 54 | } 55 | return [classNameStr deleteSpaceAndNewLine]; 56 | } else { 57 | NSString *tempStr0 = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 58 | NSArray *itemArray = [tempStr0 componentsSeparatedByString:@" "]; 59 | if (![tempStr0 hasPrefix:@"@property"] && [itemArray count] == 2) { 60 | classNameStr = [itemArray[0] deleteSpaceAndNewLine]; 61 | return classNameStr; 62 | } 63 | } 64 | return classNameStr; 65 | } 66 | 67 | - (NSString *)fetchPropertyNameStr { 68 | NSString *propertyNameStr = nil; 69 | 70 | if ([self containsString:@"*"]) { 71 | NSString *tempStr = [self deleteSpaceAndNewLine]; 72 | NSString *propertyNameStr = [tempStr stringBetweenLeftStr:@"*" andRightStr:@";"]; 73 | return [propertyNameStr deleteSpaceAndNewLine]; 74 | } else { 75 | NSString *tempStr0 = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 76 | NSArray *itemArray = [tempStr0 componentsSeparatedByString:@" "]; 77 | if (![tempStr0 hasPrefix:@"@property"] && [itemArray count] == 2) { 78 | propertyNameStr = [itemArray[1] deleteSpaceAndNewLine]; 79 | NSRange tempRange = [propertyNameStr rangeOfString:@";"]; 80 | if (tempRange.location != NSNotFound) { 81 | propertyNameStr = [propertyNameStr substringToIndex:tempRange.location]; 82 | } 83 | return propertyNameStr; 84 | } 85 | } 86 | return propertyNameStr; 87 | } 88 | 89 | - (BOOL)checkHasContainsOneOfStrs:(NSArray *)strArray andNotContainsOneOfStrs:(NSArray *)noHasStrsArray { 90 | BOOL tag0Success = NO; 91 | BOOL tag1Success = YES; 92 | for (NSString *tempStr in strArray) { 93 | if ([self containsString:tempStr]) { 94 | tag0Success = YES; 95 | } 96 | } 97 | for (NSString *tempStr in noHasStrsArray) { 98 | if ([self containsString:tempStr]) { 99 | tag1Success = NO; 100 | } 101 | } 102 | return tag0Success && tag1Success; 103 | } 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /GHWExtension/addComment/GHWAddCommentManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // GHWAddCommentManager.h 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/9/4. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface GHWAddCommentManager : NSObject 13 | 14 | + (GHWAddCommentManager *)sharedInstane; 15 | 16 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /GHWExtension/addComment/GHWAddCommentManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // GHWAddCommentManager.m 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/9/4. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "GHWAddCommentManager.h" 10 | #import "GHWExtensionConst.h" 11 | 12 | @interface GHWAddCommentManager () 13 | 14 | 15 | @end 16 | 17 | @implementation GHWAddCommentManager 18 | 19 | + (GHWAddCommentManager *)sharedInstane { 20 | static dispatch_once_t predicate; 21 | static GHWAddCommentManager * sharedInstane; 22 | dispatch_once(&predicate, ^{ 23 | sharedInstane = [[GHWAddCommentManager alloc] init]; 24 | }); 25 | return sharedInstane; 26 | } 27 | 28 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation { 29 | XCSourceTextRange *rang = invocation.buffer.selections[0]; 30 | NSInteger insertIndex = rang.start.line; 31 | 32 | for (NSInteger i = insertIndex; i < [invocation.buffer.lines count]; i++) { 33 | if ([[invocation.buffer.lines[i] deleteSpaceAndNewLine] hasPrefix:@"-"] || 34 | [[invocation.buffer.lines[i] deleteSpaceAndNewLine] hasPrefix:@"+"]) { 35 | insertIndex = i; 36 | break; 37 | } 38 | } 39 | 40 | NSMutableString *funcStr = [NSMutableString string]; 41 | for (NSInteger i = insertIndex; i < [invocation.buffer.lines count]; i++) { 42 | NSString *contentStr = invocation.buffer.lines[i]; 43 | if (![contentStr containsString:@"{"]) { 44 | [funcStr appendString:contentStr]; 45 | } else { 46 | NSRange range = [contentStr rangeOfString:@"{"]; 47 | [funcStr appendString:[contentStr substringToIndex:range.location]]; 48 | break; 49 | } 50 | } 51 | 52 | NSArray *commentHeaderLines = [kAddCommentHeaderExtensionCode componentsSeparatedByString:@"\n"]; 53 | NSArray *commentFooterLines = [kAddCommentFooterExtensionCode componentsSeparatedByString:@"\n"]; 54 | NSArray *commentFooterNoParamsLines = [kAddCommentFooterNoParamsExtensionCode componentsSeparatedByString:@"\n"]; 55 | 56 | NSArray *commentLines = [funcStr componentsSeparatedByString:@":"]; 57 | 58 | 59 | NSMutableArray *mCommentLines = [NSMutableArray arrayWithArray:commentLines]; 60 | [mCommentLines removeObjectAtIndex:0]; 61 | 62 | NSMutableArray *argsArray = [NSMutableArray array]; 63 | [argsArray addObjectsFromArray:commentHeaderLines]; 64 | for (int i = 0; i < [mCommentLines count]; i++) { 65 | NSString *tempStr = [self fetchArgumentsWithStr:mCommentLines[i]]; 66 | if (tempStr) { 67 | 68 | [argsArray addObject:[NSString stringWithFormat:@" * @param %@", tempStr]]; 69 | } 70 | } 71 | 72 | if ([[invocation.buffer.lines[insertIndex] deleteSpaceAndNewLine] containsString:@"(void)"]) { 73 | [argsArray addObject:@" */"]; 74 | } else { 75 | if ([argsArray count] > [commentHeaderLines count]) { 76 | [argsArray addObjectsFromArray:commentFooterLines]; 77 | } else { 78 | [argsArray addObjectsFromArray:commentFooterNoParamsLines]; 79 | } 80 | } 81 | 82 | [invocation.buffer.lines insertObjects:argsArray atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(insertIndex, [argsArray count])]]; 83 | } 84 | 85 | - (NSString *)fetchArgumentsWithStr:(NSString *)str { 86 | NSRange tempRange = [str rangeOfString:@")" options:NSBackwardsSearch]; 87 | NSString *subStr = [[str substringFromIndex:tempRange.location + 1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 88 | 89 | 90 | NSString *argStr = nil; 91 | NSArray *argArray = [subStr componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 92 | if ([argArray count]) { 93 | argStr = [argArray[0] deleteSpaceAndNewLine]; 94 | if ([argStr containsString:@"{"]) { 95 | argStr = [argStr stringByReplacingOccurrencesOfString:@"{" withString:@""]; 96 | } 97 | } 98 | return argStr; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /GHWExtension/addImport/GHWAddImportManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // GHWAddImportManager.h 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/9/15. 6 | // Copyright © 2019 Jingyao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface GHWAddImportManager : NSObject 14 | 15 | + (GHWAddImportManager *)sharedInstane; 16 | 17 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /GHWExtension/addImport/GHWAddImportManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // GHWAddImportManager.m 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/9/15. 6 | // Copyright © 2019 Jingyao. All rights reserved. 7 | // 8 | 9 | #import "GHWAddImportManager.h" 10 | #import "GHWExtensionConst.h" 11 | 12 | @implementation GHWAddImportManager 13 | 14 | + (GHWAddImportManager *)sharedInstane { 15 | static dispatch_once_t predicate; 16 | static GHWAddImportManager * sharedInstane; 17 | dispatch_once(&predicate, ^{ 18 | sharedInstane = [[GHWAddImportManager alloc] init]; 19 | }); 20 | return sharedInstane; 21 | } 22 | 23 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation { 24 | if (![invocation.buffer.selections count]) { 25 | return; 26 | } 27 | 28 | XCSourceTextRange *selectRange = invocation.buffer.selections[0]; 29 | NSInteger startLine = selectRange.start.line; 30 | NSInteger endLine = selectRange.end.line; 31 | NSInteger startColumn = selectRange.start.column; 32 | NSInteger endColumn = selectRange.end.column; 33 | 34 | if (startLine != endLine || startColumn == endColumn) { 35 | return; 36 | } 37 | 38 | NSString *selectLineStr = invocation.buffer.lines[startLine]; 39 | NSString *selectContentStr = [[selectLineStr substringWithRange:NSMakeRange(startColumn, endColumn - startColumn)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 40 | if ([selectContentStr length] == 0) { 41 | return; 42 | } 43 | NSString *insertStr = [NSString stringWithFormat:@"#import \"%@.h\"", selectContentStr]; 44 | 45 | NSInteger lastImportIndex = -1; 46 | for (NSInteger i = 0; i < [invocation.buffer.lines count]; i++) { 47 | NSString *contentStr = [invocation.buffer.lines[i] deleteSpaceAndNewLine]; 48 | if ([contentStr hasPrefix:@"#import"]) { 49 | lastImportIndex = i; 50 | } 51 | } 52 | 53 | NSInteger alreadyIndex = [invocation.buffer.lines indexOfFirstItemContainStr:insertStr]; 54 | if (alreadyIndex != NSNotFound) { 55 | return; 56 | } 57 | 58 | NSInteger insertIndex = 0; 59 | if (lastImportIndex != -1) { 60 | insertIndex = lastImportIndex + 1; 61 | } 62 | [invocation.buffer.lines insertObject:insertStr atIndex:insertIndex]; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /GHWExtension/addLazyCode/GHWAddLazyCodeManager.h: -------------------------------------------------------------------------------- 1 | 2 | // GHWAddLazyCodeManager.h 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019年 黑化肥发灰. All rights reserved. 7 | 8 | 9 | #import 10 | 11 | @interface GHWAddLazyCodeManager : NSObject 12 | 13 | +(GHWAddLazyCodeManager *)sharedInstane; 14 | /** 15 | 自动添加视图布局 && 设置Getter方法 && 自动AddSubView 16 | @param invocation 获取选中的字符流 17 | */ 18 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /GHWExtension/addLazyCode/GHWAddLazyCodeManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // GHWAddLazyCodeManager.m 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019年 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "GHWAddLazyCodeManager.h" 10 | #import "NSString+Extension.h" 11 | #import "GHWExtensionConst.h" 12 | 13 | @interface GHWAddLazyCodeManager () 14 | 15 | @property (nonatomic, copy) NSMutableArray *lazyArray; 16 | @property (nonatomic, copy) NSMutableArray *delegateMethodsArray; 17 | 18 | @end 19 | 20 | @implementation GHWAddLazyCodeManager 21 | 22 | +(GHWAddLazyCodeManager *)sharedInstane{ 23 | static dispatch_once_t predicate; 24 | static GHWAddLazyCodeManager * sharedInstane; 25 | dispatch_once(&predicate, ^{ 26 | sharedInstane = [[GHWAddLazyCodeManager alloc] init]; 27 | }); 28 | return sharedInstane; 29 | } 30 | 31 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation { 32 | for (XCSourceTextRange *rang in invocation.buffer.selections) { 33 | [self initWithFormaterArray:rang invocation:invocation]; 34 | } 35 | } 36 | -(void)initWithFormaterArray:(XCSourceTextRange *)selectedTextRange invocation:(XCSourceEditorCommandInvocation *)invocation { 37 | [self.lazyArray removeAllObjects]; 38 | [self.delegateMethodsArray removeAllObjects]; 39 | NSInteger startLine = selectedTextRange.start.line; 40 | NSInteger endLine = selectedTextRange.end.line; 41 | 42 | for (NSInteger i = startLine; i <= endLine; i++) { 43 | NSString *contentStr = invocation.buffer.lines[i]; 44 | 45 | if ([[contentStr deleteSpaceAndNewLine] length] == 0) { 46 | continue; 47 | } 48 | // 获取类名 49 | NSString *classNameStr = [contentStr fetchClassNameStr]; 50 | // 获取属性名或者变量名 51 | NSString *propertyNameStr = [contentStr fetchPropertyNameStr]; 52 | if (!classNameStr || !propertyNameStr) { 53 | continue; 54 | } 55 | 56 | 57 | 58 | // 修改对应属性行, 规范化 59 | NSString *replaceStr = [NSString stringWithFormat:@"@property (nonatomic, strong) %@ *%@", classNameStr, propertyNameStr]; 60 | if (![contentStr containsString:@"*"]) { 61 | replaceStr = [NSString stringWithFormat:@"@property (nonatomic, assign) %@ %@", classNameStr, propertyNameStr]; 62 | } 63 | NSRange suffixRange = [contentStr rangeOfString:@";"]; 64 | if (suffixRange.location != NSNotFound) { 65 | NSString *suffixStr = [contentStr substringFromIndex:suffixRange.location]; 66 | [invocation.buffer.lines replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%@%@", replaceStr, suffixStr]]; 67 | } else { 68 | [invocation.buffer.lines replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%@%@", replaceStr, @";"]]; 69 | } 70 | if (![invocation.buffer.lines[i] containsString:@"*"]) { 71 | continue; 72 | } 73 | 74 | 75 | 76 | //懒加载 77 | NSArray *lazyGetArray = [self fetchGetterForClassName:classNameStr andPropertyName:propertyNameStr]; 78 | if (lazyGetArray.count > 1) { 79 | __block NSString *firstStr = lazyGetArray[1]; 80 | [lazyGetArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 81 | if ([[(NSString *)obj deleteSpaceAndNewLine] hasPrefix:@"-"]) { 82 | firstStr = (NSString *)obj; 83 | } 84 | }]; 85 | 86 | NSString *currentClassName = [invocation.buffer.lines fetchCurrentClassNameWithCurrentIndex:startLine]; 87 | NSInteger impIndex = [invocation.buffer.lines indexOfFirstItemContainStrsArray:@[kImplementation, currentClassName]]; 88 | NSInteger endIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kEnd fromIndex:impIndex]; 89 | NSInteger existIndex = [invocation.buffer.lines indexOfFirstItemContainStr:firstStr fromIndex:impIndex andToIndex:endIndex]; 90 | BOOL alreadyExistLazyMethod = [self alreadyExistsLazyMethodWithClassName:classNameStr andPropertyName:propertyNameStr andInvocation:invocation andStartLine:startLine]; 91 | if (existIndex == NSNotFound && alreadyExistLazyMethod == NO) { 92 | [self.lazyArray addObject:lazyGetArray]; 93 | // 协议方法 94 | NSArray *delegateMethodLinesArray = [self fetchMethodsLinesArrayWithClassName:classNameStr andFromIndex:startLine andInvocation:invocation]; 95 | if ([delegateMethodLinesArray count]) { 96 | [self.delegateMethodsArray addObject:delegateMethodLinesArray]; 97 | } 98 | } else { 99 | // [self fixPropertyWithStartLine:i andEndLine:i andInvocation:invocation]; 100 | } 101 | 102 | } 103 | 104 | // 在 <>里面加上 UITableViewDelegate 等 105 | [self addDelegateDeclareWithClassName:classNameStr andInvocation:invocation andStartIndex:startLine]; 106 | } 107 | [self addAllDelegateMethodList:invocation andStartLine:startLine]; 108 | [self addBufferInsertInvocation:invocation andFromIndex:startLine]; 109 | 110 | // 修改对应属性行, 规范化 111 | 112 | // [self fixPropertyWithStartLine:startLine andEndLine:endLine andInvocation:invocation]; 113 | } 114 | 115 | // 修改对应属性行, 规范化 116 | - (void)fixPropertyWithStartLine:(NSInteger)startLine 117 | andEndLine:(NSInteger)endLine 118 | andInvocation:(XCSourceEditorCommandInvocation *)invocation { 119 | 120 | for (NSInteger i = startLine; i <= endLine; i++) { 121 | NSString *contentStr = invocation.buffer.lines[i]; 122 | 123 | if ([[contentStr deleteSpaceAndNewLine] length] == 0) { 124 | continue; 125 | } 126 | // 获取类名 127 | NSString *classNameStr = [contentStr fetchClassNameStr]; 128 | // 获取属性名或者变量名 129 | NSString *propertyNameStr = [contentStr fetchPropertyNameStr]; 130 | if (!classNameStr || !propertyNameStr) { 131 | continue; 132 | } 133 | 134 | // 修改对应属性行, 规范化 135 | NSString *replaceStr = [NSString stringWithFormat:@"@property (nonatomic, strong) %@ *%@", classNameStr, propertyNameStr]; 136 | if (![contentStr containsString:@"*"]) { 137 | replaceStr = [NSString stringWithFormat:@"@property (nonatomic, assign) %@ %@", classNameStr, propertyNameStr]; 138 | } 139 | NSRange suffixRange = [contentStr rangeOfString:@";"]; 140 | if (suffixRange.location != NSNotFound) { 141 | NSString *suffixStr = [contentStr substringFromIndex:suffixRange.location]; 142 | [invocation.buffer.lines replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%@%@", replaceStr, suffixStr]]; 143 | } else { 144 | [invocation.buffer.lines replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%@%@", replaceStr, @";"]]; 145 | } 146 | if (![invocation.buffer.lines[i] containsString:@"*"]) { 147 | continue; 148 | } 149 | } 150 | } 151 | 152 | - (BOOL)alreadyExistsLazyMethodWithClassName:(NSString *)className 153 | andPropertyName:(NSString *)propertyName 154 | andInvocation:(XCSourceEditorCommandInvocation *)invocation 155 | andStartLine:(NSInteger)startLine{ 156 | NSString *lazyHeadStr = [NSString stringWithFormat:@"-(%@*)%@", className, propertyName]; 157 | NSString *lazyHeadStr1 = [NSString stringWithFormat:@"-(%@*)%@{", className, propertyName]; 158 | 159 | NSString *currentClassName = [invocation.buffer.lines fetchCurrentClassNameWithCurrentIndex:startLine]; 160 | NSInteger impIndex = [invocation.buffer.lines indexOfFirstItemContainStrsArray:@[kImplementation, currentClassName]]; 161 | NSInteger endIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kEnd fromIndex:impIndex]; 162 | BOOL existLazyMethod = NO; 163 | for (NSInteger i = impIndex; i < endIndex; i++) { 164 | NSString *contentStr = [invocation.buffer.lines[i] deleteSpaceAndNewLine]; 165 | if ([contentStr isEqualToString:lazyHeadStr] || [contentStr isEqualToString:lazyHeadStr1]) { 166 | existLazyMethod = YES; 167 | } 168 | } 169 | return existLazyMethod; 170 | } 171 | 172 | - (void)addDelegateDeclareWithClassName:(NSString *)className 173 | andInvocation:(XCSourceEditorCommandInvocation *)invocation 174 | andStartIndex:(NSInteger)startIndex { 175 | if ([[self fetchDelegateDeclareStrWithClassName:className] length] == 0) { 176 | return; 177 | } 178 | for (NSInteger i = startIndex; i > 0; i--) { 179 | NSString *contentStr = invocation.buffer.lines[i]; 180 | if ([contentStr containsString:kInterface]) { 181 | NSString *tempStr = [self fetchDelegateDeclareStrWithClassName:className]; 182 | NSString *tempStr0 = @""; 183 | if ([tempStr containsString:@","]) { 184 | NSArray *tempArray = [tempStr componentsSeparatedByString:@","]; 185 | tempStr0 = [tempArray[0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 186 | } else { 187 | tempStr0 = tempStr; 188 | } 189 | if ([contentStr containsString:tempStr0]) { 190 | break; 191 | } 192 | 193 | if ([contentStr containsString:@"<"] && [contentStr containsString:@">"]) { 194 | NSRange tempRange = [contentStr rangeOfString:@"<"]; 195 | NSString *frontStr = [contentStr substringToIndex:tempRange.location]; 196 | NSString *endStr = [contentStr substringFromIndex:tempRange.location + 1]; 197 | invocation.buffer.lines[i] = [NSString stringWithFormat:@"%@<%@, %@", frontStr, [self fetchDelegateDeclareStrWithClassName:className], endStr]; 198 | } else { 199 | invocation.buffer.lines[i] = [NSString stringWithFormat:@"%@ <%@>", [contentStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]], [self fetchDelegateDeclareStrWithClassName:className]]; 200 | } 201 | 202 | break; 203 | } 204 | } 205 | } 206 | 207 | - (NSString *)fetchDelegateDeclareStrWithClassName:(NSString *)classNameStr { 208 | if ([classNameStr isEqualToString:kUITableView]) { 209 | return @"UITableViewDelegate, UITableViewDataSource"; 210 | } else if ([classNameStr isEqualToString:kUICollectionView]) { 211 | return @"UICollectionViewDelegate, UICollectionViewDataSource"; 212 | } else if ([classNameStr isEqualToString:kUIScrollView]) { 213 | return @"UIScrollViewDelegate"; 214 | } 215 | return @""; 216 | } 217 | 218 | - (NSArray *)fetchMethodsLinesArrayWithClassName:(NSString *)classNameStr andFromIndex:(NSInteger)startLine andInvocation:(XCSourceEditorCommandInvocation *)invocation { 219 | NSString *currentClassName = [invocation.buffer.lines fetchCurrentClassNameWithCurrentIndex:startLine]; 220 | NSInteger impIndex = [invocation.buffer.lines indexOfFirstItemContainStrsArray:@[kImplementation, currentClassName]]; 221 | NSInteger endIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kEnd fromIndex:impIndex]; 222 | NSString *insertStr = nil; 223 | NSArray *formaterArr = nil; 224 | if ([classNameStr isEqualToString:kUITableView]) { 225 | formaterArr = [[kAddLazyCodeTableViewDataSourceAndDelegate componentsSeparatedByString:@"\n"] arrayByAddingObject:@""]; 226 | insertStr = @"- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section"; 227 | } else if ([classNameStr isEqualToString:kUICollectionView]) { 228 | formaterArr = [[kAddLazyCodeUICollectionViewDelegate componentsSeparatedByString:@"\n"] arrayByAddingObject:@""]; 229 | insertStr = @"- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section"; 230 | } else if ([classNameStr isEqualToString:kUIScrollView]) { 231 | formaterArr = [[kAddLazyCodeUIScrollViewDelegate componentsSeparatedByString:@"\n"] arrayByAddingObject:@""]; 232 | insertStr = @"- (void)scrollViewDidScroll:(UIScrollView *)scrollView"; 233 | } 234 | if (insertStr) { 235 | NSInteger alreadyIndex = [invocation.buffer.lines indexOfFirstItemContainStr:insertStr fromIndex:impIndex andToIndex:endIndex]; 236 | if (alreadyIndex != NSNotFound) { 237 | formaterArr = nil; 238 | } 239 | } 240 | 241 | return formaterArr; 242 | } 243 | 244 | //进行判断进行替换 245 | -(void)addBufferInsertInvocation:(XCSourceEditorCommandInvocation *)invocation andFromIndex:(NSInteger)startLine { 246 | NSString *currentClassName = [invocation.buffer.lines fetchCurrentClassNameWithCurrentIndex:startLine]; 247 | NSInteger impIndex = [invocation.buffer.lines indexOfFirstItemContainStrsArray:@[kImplementation, currentClassName]]; 248 | NSInteger endIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kEnd fromIndex:impIndex]; 249 | NSInteger insertIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kGetterSetterPragmaMark fromIndex:impIndex andToIndex:endIndex]; 250 | if (insertIndex == NSNotFound) { 251 | insertIndex = endIndex; 252 | } else { 253 | insertIndex = insertIndex + 1; 254 | } 255 | for (int i = 0; i < [self.lazyArray count]; i++) { 256 | NSArray *tempArray = [self.lazyArray objectAtIndex:i]; 257 | [invocation.buffer.lines insertItemsOfArray:tempArray fromIndex:insertIndex]; 258 | insertIndex = insertIndex + [tempArray count]; 259 | } 260 | } 261 | 262 | 263 | -(void)addBufferWithCurrentLineIndex:(NSInteger)currentLineIndex formaterArray:(NSMutableArray *)formaterArray invocation:(XCSourceEditorCommandInvocation *)invocation { 264 | //这里的循环主要就是开始 在检测到的下一行开始轮询 265 | for (NSInteger i = currentLineIndex + 1; i < formaterArray.count + currentLineIndex + 1; i ++) { 266 | NSArray *formatArr = [formaterArray objectAtIndex:formaterArray.count - i - 1 + (currentLineIndex + 1 )]; 267 | for (int j = 0; j 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface GHWInitViewManager : NSObject 13 | 14 | + (GHWInitViewManager *)sharedInstane; 15 | 16 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /GHWExtension/initView/GHWInitViewManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // GHWInitViewManager.m 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "GHWInitViewManager.h" 10 | #import "GHWExtensionConst.h" 11 | 12 | @interface GHWInitViewManager () 13 | 14 | @property (nonatomic, strong) NSMutableIndexSet *indexSet; 15 | 16 | @end 17 | 18 | @implementation GHWInitViewManager 19 | 20 | + (GHWInitViewManager *)sharedInstane { 21 | static dispatch_once_t predicate; 22 | static GHWInitViewManager * sharedInstane; 23 | dispatch_once(&predicate, ^{ 24 | sharedInstane = [[GHWInitViewManager alloc] init]; 25 | }); 26 | return sharedInstane; 27 | } 28 | 29 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation { 30 | [self.indexSet removeAllIndexes]; 31 | 32 | // 添加 extension 代码 33 | NSString *className = [invocation.buffer.lines fetchClassName]; 34 | if ([invocation.buffer.lines indexOfFirstItemContainStr:[NSString stringWithFormat:@"@interface %@ ()", className]] == NSNotFound) { 35 | NSString *extensionStr = [NSString stringWithFormat:kInitViewExtensionCode, className]; 36 | NSArray *contentArray = [extensionStr componentsSeparatedByString:@"\n"]; 37 | NSInteger impIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kImplementation]; 38 | [invocation.buffer.lines insertItemsOfArray:contentArray fromIndex:impIndex]; 39 | } 40 | 41 | if ([[className lowercaseString] hasSuffix:@"view"] || 42 | [[className lowercaseString] hasSuffix:@"bar"] || 43 | [[className lowercaseString] hasSuffix:@"collectioncell"] || 44 | [[className lowercaseString] hasSuffix:@"collectionviewcell"]) { 45 | // 添加 Life Cycle 代码 46 | if ([invocation.buffer.lines indexOfFirstItemContainStr:@"- (instancetype)initWithFrame"] == NSNotFound) { 47 | [self deleteCodeWithInvocation:invocation]; 48 | NSInteger lifeCycleIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kImplementation]; 49 | if (lifeCycleIndex != NSNotFound) { 50 | lifeCycleIndex = lifeCycleIndex + 1; 51 | NSString *lifeCycleStr = kInitViewLifeCycleCode; 52 | NSArray *lifeCycleContentArray = [lifeCycleStr componentsSeparatedByString:@"\n"]; 53 | [invocation.buffer.lines insertItemsOfArray:lifeCycleContentArray fromIndex:lifeCycleIndex]; 54 | } 55 | } 56 | } else if ([[className lowercaseString] hasSuffix:@"tableviewcell"] || 57 | [[className lowercaseString] hasSuffix:@"tablecell"]) { 58 | // 添加 Life Cycle 代码 59 | if ([invocation.buffer.lines indexOfFirstItemContainStr:@"(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier"] == NSNotFound) { 60 | [self deleteCodeWithInvocation:invocation]; 61 | NSInteger lifeCycleIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kImplementation]; 62 | if (lifeCycleIndex != NSNotFound) { 63 | lifeCycleIndex = lifeCycleIndex + 1; 64 | NSString *lifeCycleStr = kInitTableViewCellLifeCycleCode; 65 | NSArray *lifeCycleContentArray = [lifeCycleStr componentsSeparatedByString:@"\n"]; 66 | [invocation.buffer.lines insertItemsOfArray:lifeCycleContentArray fromIndex:lifeCycleIndex]; 67 | } 68 | } 69 | } else if ([[className lowercaseString] hasSuffix:@"controller"] || 70 | [className hasSuffix:@"VC"] || 71 | [className hasSuffix:@"Vc"]) { 72 | // 添加 Life Cycle 代码 73 | if ([invocation.buffer.lines indexOfFirstItemContainStr:kGetterSetterPragmaMark] == NSNotFound) { 74 | [self deleteCodeWithInvocation:invocation]; 75 | NSInteger lifeCycleIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kImplementation]; 76 | if (lifeCycleIndex != NSNotFound) { 77 | lifeCycleIndex = lifeCycleIndex + 1; 78 | NSString *lifeCycleStr = kInitViewControllerLifeCycleCode; 79 | NSArray *lifeCycleContentArray = [lifeCycleStr componentsSeparatedByString:@"\n"]; 80 | [invocation.buffer.lines insertItemsOfArray:lifeCycleContentArray fromIndex:lifeCycleIndex]; 81 | } 82 | } 83 | } 84 | 85 | } 86 | 87 | - (void)deleteCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation { 88 | NSInteger impIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kImplementation]; 89 | NSInteger endIndex = [invocation.buffer.lines indexOfFirstItemContainStr:kEnd fromIndex:impIndex]; 90 | if (impIndex != NSNotFound && endIndex != NSNotFound) { 91 | for (NSInteger i = impIndex + 1; i < endIndex - 1; i++) { 92 | NSString *contentStr = [invocation.buffer.lines[i] deleteSpaceAndNewLine]; 93 | if ([contentStr length]) { 94 | [self.indexSet addIndex:i]; 95 | } 96 | } 97 | } 98 | if ([self.indexSet count]) { 99 | [invocation.buffer.lines removeObjectsAtIndexes:self.indexSet]; 100 | } 101 | } 102 | 103 | 104 | - (NSMutableIndexSet *)indexSet{ 105 | if (!_indexSet) { 106 | _indexSet = [[NSMutableIndexSet alloc] init]; 107 | } 108 | return _indexSet; 109 | } 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /GHWExtension/sortImport/GHWSortImportManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // GHWSortImportManager.h 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface GHWSortImportManager : NSObject 14 | 15 | + (GHWSortImportManager *)sharedInstane; 16 | 17 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation; 18 | 19 | 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /GHWExtension/sortImport/GHWSortImportManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // GHWSortImportManager.m 3 | // GHWExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/30. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "GHWSortImportManager.h" 10 | #import "GHWExtensionConst.h" 11 | 12 | @interface GHWSortImportManager () 13 | 14 | @property (nonatomic, strong) NSString *classNameImportStr; 15 | 16 | @property (nonatomic, strong) NSMutableArray *controllerArray; 17 | @property (nonatomic, strong) NSMutableArray *viewsArray; 18 | @property (nonatomic, strong) NSMutableArray *managerArray; 19 | @property (nonatomic, strong) NSMutableArray *thirdLibArray; 20 | @property (nonatomic, strong) NSMutableArray *modelArray; 21 | @property (nonatomic, strong) NSMutableArray *categoryArray; 22 | @property (nonatomic, strong) NSMutableArray *otherArray; 23 | @property (nonatomic, strong) NSMutableIndexSet *indexSet; 24 | 25 | @property (nonatomic, assign) BOOL hasSelectedImportLines; 26 | @end 27 | 28 | @implementation GHWSortImportManager 29 | 30 | + (GHWSortImportManager *)sharedInstane { 31 | static dispatch_once_t predicate; 32 | static GHWSortImportManager * sharedInstane; 33 | dispatch_once(&predicate, ^{ 34 | sharedInstane = [[GHWSortImportManager alloc] init]; 35 | }); 36 | return sharedInstane; 37 | } 38 | 39 | - (void)processCodeWithInvocation:(XCSourceEditorCommandInvocation *)invocation { 40 | NSLog(@"sortImport"); 41 | self.classNameImportStr = nil; 42 | [self.controllerArray removeAllObjects]; 43 | [self.viewsArray removeAllObjects]; 44 | [self.managerArray removeAllObjects]; 45 | [self.thirdLibArray removeAllObjects]; 46 | [self.modelArray removeAllObjects]; 47 | [self.categoryArray removeAllObjects]; 48 | [self.otherArray removeAllObjects]; 49 | [self.indexSet removeAllIndexes]; 50 | 51 | NSInteger endIndex = 0; 52 | NSInteger startIndex = 0; 53 | if ([invocation.buffer.selections count] == 0) { 54 | startIndex = [self indexOfFirstInsertLineOfArray:invocation.buffer.lines]; 55 | endIndex = [invocation.buffer.lines count] - 1; 56 | self.hasSelectedImportLines = NO; 57 | } else { 58 | XCSourceTextRange *selectRange = invocation.buffer.selections[0]; 59 | startIndex = selectRange.start.line; 60 | endIndex = selectRange.end.line; 61 | 62 | if (startIndex == endIndex) { 63 | startIndex = [self indexOfFirstInsertLineOfArray:invocation.buffer.lines]; 64 | endIndex = [invocation.buffer.lines count] - 1; 65 | self.hasSelectedImportLines = NO; 66 | 67 | } else { 68 | self.hasSelectedImportLines = YES; 69 | } 70 | 71 | } 72 | 73 | NSInteger importStartIndex = startIndex < [self indexOfFirstInsertLineOfArray:invocation.buffer.lines] + 1 ? [self indexOfFirstInsertLineOfArray:invocation.buffer.lines] + 1 : startIndex; 74 | NSString *classNameStr = [[invocation.buffer.lines fetchClassName] lowercaseString]; 75 | for (NSInteger i = startIndex; i <= endIndex; i++) { 76 | NSString *contentStr = [[invocation.buffer.lines[i] deleteSpaceAndNewLine] lowercaseString]; 77 | if (![contentStr hasPrefix:@"#import"]) { 78 | if ([contentStr length] == 0 && self.hasSelectedImportLines) { 79 | [self.indexSet addIndex:i]; 80 | } 81 | continue; 82 | } 83 | 84 | if ([contentStr checkHasContainsOneOfStrs:@[[NSString stringWithFormat:@"%@.h", classNameStr]] 85 | andNotContainsOneOfStrs:@[@"+"]]) { 86 | self.classNameImportStr = invocation.buffer.lines[i]; 87 | } else if ([contentStr checkHasContainsOneOfStrs:@[@"view.h\"", @"bar.h\"", @"cell.h\""] 88 | andNotContainsOneOfStrs:@[@"+"]]) { 89 | [self.viewsArray addObject:invocation.buffer.lines[i]]; 90 | } else if ([contentStr checkHasContainsOneOfStrs:@[@"manager.h\"", @"logic.h\"", @"helper.h\"", @"services.h\"", @"service.h\""] 91 | andNotContainsOneOfStrs:@[@"+"]]) { 92 | [self.managerArray addObject:invocation.buffer.lines[i]]; 93 | } else if ([contentStr checkHasContainsOneOfStrs:@[@"controller.h\"", @"VC.h\"", @"Vc.h\"", @"vc.h\""] 94 | andNotContainsOneOfStrs:@[@"+"]]) { 95 | [self.controllerArray addObject:invocation.buffer.lines[i]]; 96 | } else if ([contentStr checkHasContainsOneOfStrs:@[@".h>"] 97 | andNotContainsOneOfStrs:@[]]) { 98 | [self.thirdLibArray addObject:invocation.buffer.lines[i]]; 99 | } else if ([contentStr checkHasContainsOneOfStrs:@[@"model.h\"", @"models.h\""] 100 | andNotContainsOneOfStrs:@[@"+"]]) { 101 | [self.modelArray addObject:invocation.buffer.lines[i]]; 102 | } else if ([contentStr containsString:@"+"]) { 103 | [self.categoryArray addObject:invocation.buffer.lines[i]]; 104 | } else { 105 | [self.otherArray addObject:invocation.buffer.lines[i]]; 106 | } 107 | } 108 | [invocation.buffer.lines printList]; 109 | [invocation.buffer.lines removeObjectsAtIndexes:self.indexSet]; 110 | 111 | [invocation.buffer.lines printList]; 112 | [invocation.buffer.lines removeObject:self.classNameImportStr]; 113 | 114 | [invocation.buffer.lines removeObjectsInArray:self.controllerArray]; 115 | [invocation.buffer.lines printList]; 116 | 117 | 118 | [invocation.buffer.lines removeObjectsInArray:self.viewsArray]; 119 | [invocation.buffer.lines printList]; 120 | 121 | [invocation.buffer.lines removeObjectsInArray:self.managerArray]; 122 | [invocation.buffer.lines printList]; 123 | 124 | [invocation.buffer.lines removeObjectsInArray:self.modelArray]; 125 | [invocation.buffer.lines printList]; 126 | 127 | [invocation.buffer.lines removeObjectsInArray:self.categoryArray]; 128 | [invocation.buffer.lines printList]; 129 | 130 | [invocation.buffer.lines removeObjectsInArray:self.thirdLibArray]; 131 | [invocation.buffer.lines printList]; 132 | 133 | [invocation.buffer.lines removeObjectsInArray:self.otherArray]; 134 | 135 | if ([self.classNameImportStr length]) { 136 | NSMutableArray *mArr = [NSMutableArray arrayWithObject:self.classNameImportStr]; 137 | [mArr addObject:@"\n"]; 138 | [invocation.buffer.lines insertItemsOfArray:mArr fromIndex:importStartIndex]; 139 | importStartIndex = importStartIndex + [mArr count]; 140 | [invocation.buffer.lines printList]; 141 | } 142 | 143 | if ([self.controllerArray count]) { 144 | self.controllerArray = [self.controllerArray arrayWithNoSameItem]; 145 | [self.controllerArray addObject:@"\n"]; 146 | [invocation.buffer.lines insertItemsOfArray:self.controllerArray fromIndex:importStartIndex]; 147 | importStartIndex = importStartIndex + [self.controllerArray count]; 148 | [invocation.buffer.lines printList]; 149 | } 150 | 151 | if ([self.viewsArray count]) { 152 | self.viewsArray = [self.viewsArray arrayWithNoSameItem]; 153 | [self.viewsArray addObject:@"\n"]; 154 | [invocation.buffer.lines insertItemsOfArray:self.viewsArray fromIndex:importStartIndex]; 155 | importStartIndex = importStartIndex + [self.viewsArray count]; 156 | [invocation.buffer.lines printList]; 157 | } 158 | if ([self.managerArray count]) { 159 | self.managerArray = [self.managerArray arrayWithNoSameItem]; 160 | [self.managerArray addObject:@"\n"]; 161 | [invocation.buffer.lines insertItemsOfArray:self.managerArray fromIndex:importStartIndex]; 162 | importStartIndex = importStartIndex + [self.managerArray count]; 163 | [invocation.buffer.lines printList]; 164 | } 165 | 166 | if ([self.modelArray count]) { 167 | self.modelArray = [self.modelArray arrayWithNoSameItem]; 168 | [self.modelArray addObject:@"\n"]; 169 | [invocation.buffer.lines insertItemsOfArray:self.modelArray fromIndex:importStartIndex]; 170 | importStartIndex = importStartIndex + [self.modelArray count]; 171 | [invocation.buffer.lines printList]; 172 | } 173 | if ([self.categoryArray count]) { 174 | self.categoryArray = [self.categoryArray arrayWithNoSameItem]; 175 | [self.categoryArray addObject:@"\n"]; 176 | [invocation.buffer.lines insertItemsOfArray:self.categoryArray fromIndex:importStartIndex]; 177 | importStartIndex = importStartIndex + [self.categoryArray count]; 178 | [invocation.buffer.lines printList]; 179 | } 180 | if ([self.thirdLibArray count]) { 181 | self.thirdLibArray = [self.thirdLibArray arrayWithNoSameItem]; 182 | [self.thirdLibArray addObject:@"\n"]; 183 | [invocation.buffer.lines insertItemsOfArray:self.thirdLibArray fromIndex:importStartIndex]; 184 | importStartIndex = importStartIndex + [self.thirdLibArray count]; 185 | [invocation.buffer.lines printList]; 186 | } 187 | if ([self.otherArray count]) { 188 | self.otherArray = [self.otherArray arrayWithNoSameItem]; 189 | [self.otherArray addObject:@"\n"]; 190 | [invocation.buffer.lines insertItemsOfArray:self.otherArray fromIndex:importStartIndex]; 191 | importStartIndex = importStartIndex + [self.otherArray count]; 192 | [invocation.buffer.lines printList]; 193 | } 194 | 195 | NSMutableIndexSet *spaceDeleteSet = [[NSMutableIndexSet alloc] init]; 196 | for (NSInteger i = importStartIndex; i < [invocation.buffer.lines count]; i++) { 197 | if ([[invocation.buffer.lines[i] deleteSpaceAndNewLine] length] == 0) { 198 | [spaceDeleteSet addIndex:i]; 199 | [invocation.buffer.lines printList]; 200 | } else { 201 | break; 202 | } 203 | } 204 | 205 | [invocation.buffer.lines removeObjectsAtIndexes:spaceDeleteSet]; 206 | 207 | // 还需要把本类的import往前面挪动 208 | } 209 | 210 | - (NSInteger)indexOfFirstInsertLineOfArray:(NSMutableArray *)mArray { 211 | NSInteger commentLastIndex = -1; 212 | for (int i = 0; i < [mArray count]; i++) { 213 | NSString *contentStr = [[mArray[i] deleteSpaceAndNewLine] lowercaseString]; 214 | if ([contentStr hasPrefix:@"//"] || [contentStr length] == 0) { 215 | if ([contentStr hasPrefix:@"//"]) { 216 | commentLastIndex = i; 217 | } 218 | continue; 219 | } 220 | break; 221 | } 222 | if (commentLastIndex == -1) { 223 | return 0; 224 | } else { 225 | return commentLastIndex + 1; 226 | } 227 | } 228 | 229 | - (NSMutableArray *)controllerArray { 230 | if (!_controllerArray) { 231 | _controllerArray = [[NSMutableArray alloc] init]; 232 | } 233 | return _controllerArray; 234 | } 235 | 236 | - (NSMutableArray *)viewsArray { 237 | if (!_viewsArray) { 238 | _viewsArray = [[NSMutableArray alloc] init]; 239 | } 240 | return _viewsArray; 241 | } 242 | 243 | - (NSMutableArray *)managerArray { 244 | if (!_managerArray) { 245 | _managerArray = [[NSMutableArray alloc] init]; 246 | } 247 | return _managerArray; 248 | } 249 | 250 | - (NSMutableArray *)thirdLibArray { 251 | if (!_thirdLibArray) { 252 | _thirdLibArray = [[NSMutableArray alloc] init]; 253 | } 254 | return _thirdLibArray; 255 | } 256 | 257 | - (NSMutableArray *)modelArray { 258 | if (!_modelArray) { 259 | _modelArray = [[NSMutableArray alloc] init]; 260 | } 261 | return _modelArray; 262 | } 263 | 264 | - (NSMutableArray *)categoryArray { 265 | if (!_categoryArray) { 266 | _categoryArray = [[NSMutableArray alloc] init]; 267 | } 268 | return _categoryArray; 269 | } 270 | 271 | - (NSMutableArray *)otherArray { 272 | if (!_otherArray) { 273 | _otherArray = [[NSMutableArray alloc] init]; 274 | } 275 | return _otherArray; 276 | } 277 | 278 | - (NSMutableIndexSet *)indexSet{ 279 | if (!_indexSet) { 280 | _indexSet = [[NSMutableIndexSet alloc] init]; 281 | } 282 | return _indexSet; 283 | } 284 | 285 | 286 | @end 287 | 288 | -------------------------------------------------------------------------------- /GHWXcodeExtension.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | ED6552302318F98E0036A04A /* GHWAddLazyCodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = ED65522C2318F98E0036A04A /* GHWAddLazyCodeManager.m */; }; 11 | ED6552372318FB180036A04A /* GHWInitViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = ED6552362318FB180036A04A /* GHWInitViewManager.m */; }; 12 | ED65523A2318FBB70036A04A /* GHWSortImportManager.m in Sources */ = {isa = PBXBuildFile; fileRef = ED6552392318FBB70036A04A /* GHWSortImportManager.m */; }; 13 | ED65524023190CE00036A04A /* NSMutableArray+GHWExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = ED65523F23190CE00036A04A /* NSMutableArray+GHWExtension.m */; }; 14 | EDA60A402317F41000B5FA3D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EDA60A3F2317F41000B5FA3D /* AppDelegate.m */; }; 15 | EDA60A432317F41000B5FA3D /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EDA60A422317F41000B5FA3D /* ViewController.m */; }; 16 | EDA60A452317F41000B5FA3D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EDA60A442317F41000B5FA3D /* Assets.xcassets */; }; 17 | EDA60A482317F41000B5FA3D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EDA60A462317F41000B5FA3D /* Main.storyboard */; }; 18 | EDA60A4B2317F41000B5FA3D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EDA60A4A2317F41000B5FA3D /* main.m */; }; 19 | EDA60A5D2317F43500B5FA3D /* SourceEditorExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = EDA60A5C2317F43500B5FA3D /* SourceEditorExtension.m */; }; 20 | EDA60A602317F43500B5FA3D /* SourceEditorCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = EDA60A5F2317F43500B5FA3D /* SourceEditorCommand.m */; }; 21 | EDA60A652317F43500B5FA3D /* GHWExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = EDA60A562317F43500B5FA3D /* GHWExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 22 | EDA60A752317F4BF00B5FA3D /* NSString+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = EDA60A722317F4BF00B5FA3D /* NSString+Extension.m */; }; 23 | EDAB4ADD25F3D0D100342C7A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDA60A582317F43500B5FA3D /* Cocoa.framework */; }; 24 | EDAB4ADF25F3D0D900342C7A /* XcodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDAB4ADE25F3D0D900342C7A /* XcodeKit.framework */; }; 25 | EDAB4AE025F3D0D900342C7A /* XcodeKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EDAB4ADE25F3D0D900342C7A /* XcodeKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 26 | EDBFBD1D231FF38000490C20 /* GHWAddCommentManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EDBFBD1C231FF38000490C20 /* GHWAddCommentManager.m */; }; 27 | EDC57717232E2EEB00445D4F /* GHWAddImportManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EDC57716232E2EEB00445D4F /* GHWAddImportManager.m */; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXContainerItemProxy section */ 31 | EDA60A632317F43500B5FA3D /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = EDA60A332317F41000B5FA3D /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = EDA60A552317F43500B5FA3D; 36 | remoteInfo = GHWExtension; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXCopyFilesBuildPhase section */ 41 | EDA60A692317F43500B5FA3D /* Embed App Extensions */ = { 42 | isa = PBXCopyFilesBuildPhase; 43 | buildActionMask = 2147483647; 44 | dstPath = ""; 45 | dstSubfolderSpec = 13; 46 | files = ( 47 | EDA60A652317F43500B5FA3D /* GHWExtension.appex in Embed App Extensions */, 48 | ); 49 | name = "Embed App Extensions"; 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | EDAB4AE125F3D0D900342C7A /* Embed Frameworks */ = { 53 | isa = PBXCopyFilesBuildPhase; 54 | buildActionMask = 2147483647; 55 | dstPath = ""; 56 | dstSubfolderSpec = 10; 57 | files = ( 58 | EDAB4AE025F3D0D900342C7A /* XcodeKit.framework in Embed Frameworks */, 59 | ); 60 | name = "Embed Frameworks"; 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXCopyFilesBuildPhase section */ 64 | 65 | /* Begin PBXFileReference section */ 66 | ED65522A2318F98E0036A04A /* GHWExtensionConst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHWExtensionConst.h; sourceTree = ""; }; 67 | ED65522C2318F98E0036A04A /* GHWAddLazyCodeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHWAddLazyCodeManager.m; sourceTree = ""; }; 68 | ED65522E2318F98E0036A04A /* GHWAddLazyCodeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHWAddLazyCodeManager.h; sourceTree = ""; }; 69 | ED6552352318FB180036A04A /* GHWInitViewManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GHWInitViewManager.h; sourceTree = ""; }; 70 | ED6552362318FB180036A04A /* GHWInitViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GHWInitViewManager.m; sourceTree = ""; }; 71 | ED6552382318FBB70036A04A /* GHWSortImportManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GHWSortImportManager.h; sourceTree = ""; }; 72 | ED6552392318FBB70036A04A /* GHWSortImportManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GHWSortImportManager.m; sourceTree = ""; }; 73 | ED65523E23190CE00036A04A /* NSMutableArray+GHWExtension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+GHWExtension.h"; sourceTree = ""; }; 74 | ED65523F23190CE00036A04A /* NSMutableArray+GHWExtension.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+GHWExtension.m"; sourceTree = ""; }; 75 | EDA60A3B2317F41000B5FA3D /* GHWXcodeExtension.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GHWXcodeExtension.app; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | EDA60A3E2317F41000B5FA3D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 77 | EDA60A3F2317F41000B5FA3D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 78 | EDA60A412317F41000B5FA3D /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 79 | EDA60A422317F41000B5FA3D /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 80 | EDA60A442317F41000B5FA3D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 81 | EDA60A472317F41000B5FA3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 82 | EDA60A492317F41000B5FA3D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 83 | EDA60A4A2317F41000B5FA3D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 84 | EDA60A4C2317F41000B5FA3D /* GHWXcodeExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GHWXcodeExtension.entitlements; sourceTree = ""; }; 85 | EDA60A562317F43500B5FA3D /* GHWExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = GHWExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 86 | EDA60A582317F43500B5FA3D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 87 | EDA60A5B2317F43500B5FA3D /* SourceEditorExtension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SourceEditorExtension.h; sourceTree = ""; }; 88 | EDA60A5C2317F43500B5FA3D /* SourceEditorExtension.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SourceEditorExtension.m; sourceTree = ""; }; 89 | EDA60A5E2317F43500B5FA3D /* SourceEditorCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SourceEditorCommand.h; sourceTree = ""; }; 90 | EDA60A5F2317F43500B5FA3D /* SourceEditorCommand.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SourceEditorCommand.m; sourceTree = ""; }; 91 | EDA60A612317F43500B5FA3D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 92 | EDA60A622317F43500B5FA3D /* GHWExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GHWExtension.entitlements; sourceTree = ""; }; 93 | EDA60A712317F4BF00B5FA3D /* NSString+Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Extension.h"; sourceTree = ""; }; 94 | EDA60A722317F4BF00B5FA3D /* NSString+Extension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Extension.m"; sourceTree = ""; }; 95 | EDAB4ADE25F3D0D900342C7A /* XcodeKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XcodeKit.framework; path = Library/Frameworks/XcodeKit.framework; sourceTree = DEVELOPER_DIR; }; 96 | EDBFBD1B231FF38000490C20 /* GHWAddCommentManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GHWAddCommentManager.h; sourceTree = ""; }; 97 | EDBFBD1C231FF38000490C20 /* GHWAddCommentManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GHWAddCommentManager.m; sourceTree = ""; }; 98 | EDC57715232E2EEB00445D4F /* GHWAddImportManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GHWAddImportManager.h; sourceTree = ""; }; 99 | EDC57716232E2EEB00445D4F /* GHWAddImportManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GHWAddImportManager.m; sourceTree = ""; }; 100 | /* End PBXFileReference section */ 101 | 102 | /* Begin PBXFrameworksBuildPhase section */ 103 | EDA60A382317F41000B5FA3D /* Frameworks */ = { 104 | isa = PBXFrameworksBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | EDA60A532317F43500B5FA3D /* Frameworks */ = { 111 | isa = PBXFrameworksBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | EDAB4ADD25F3D0D100342C7A /* Cocoa.framework in Frameworks */, 115 | EDAB4ADF25F3D0D900342C7A /* XcodeKit.framework in Frameworks */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | /* End PBXFrameworksBuildPhase section */ 120 | 121 | /* Begin PBXGroup section */ 122 | ED65522B2318F98E0036A04A /* addLazyCode */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | ED65522E2318F98E0036A04A /* GHWAddLazyCodeManager.h */, 126 | ED65522C2318F98E0036A04A /* GHWAddLazyCodeManager.m */, 127 | ); 128 | path = addLazyCode; 129 | sourceTree = ""; 130 | }; 131 | ED6552322318FA500036A04A /* initView */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | ED6552352318FB180036A04A /* GHWInitViewManager.h */, 135 | ED6552362318FB180036A04A /* GHWInitViewManager.m */, 136 | ); 137 | path = initView; 138 | sourceTree = ""; 139 | }; 140 | ED6552342318FA720036A04A /* sortImport */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | ED6552382318FBB70036A04A /* GHWSortImportManager.h */, 144 | ED6552392318FBB70036A04A /* GHWSortImportManager.m */, 145 | ); 146 | path = sortImport; 147 | sourceTree = ""; 148 | }; 149 | EDA60A322317F41000B5FA3D = { 150 | isa = PBXGroup; 151 | children = ( 152 | EDA60A3D2317F41000B5FA3D /* GHWXcodeExtension */, 153 | EDA60A5A2317F43500B5FA3D /* GHWExtension */, 154 | EDA60A572317F43500B5FA3D /* Frameworks */, 155 | EDA60A3C2317F41000B5FA3D /* Products */, 156 | ); 157 | sourceTree = ""; 158 | }; 159 | EDA60A3C2317F41000B5FA3D /* Products */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | EDA60A3B2317F41000B5FA3D /* GHWXcodeExtension.app */, 163 | EDA60A562317F43500B5FA3D /* GHWExtension.appex */, 164 | ); 165 | name = Products; 166 | sourceTree = ""; 167 | }; 168 | EDA60A3D2317F41000B5FA3D /* GHWXcodeExtension */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | EDA60A3E2317F41000B5FA3D /* AppDelegate.h */, 172 | EDA60A3F2317F41000B5FA3D /* AppDelegate.m */, 173 | EDA60A412317F41000B5FA3D /* ViewController.h */, 174 | EDA60A422317F41000B5FA3D /* ViewController.m */, 175 | EDA60A442317F41000B5FA3D /* Assets.xcassets */, 176 | EDA60A462317F41000B5FA3D /* Main.storyboard */, 177 | EDA60A492317F41000B5FA3D /* Info.plist */, 178 | EDA60A4A2317F41000B5FA3D /* main.m */, 179 | EDA60A4C2317F41000B5FA3D /* GHWXcodeExtension.entitlements */, 180 | ); 181 | path = GHWXcodeExtension; 182 | sourceTree = ""; 183 | }; 184 | EDA60A572317F43500B5FA3D /* Frameworks */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | EDAB4ADE25F3D0D900342C7A /* XcodeKit.framework */, 188 | EDA60A582317F43500B5FA3D /* Cocoa.framework */, 189 | ); 190 | name = Frameworks; 191 | sourceTree = ""; 192 | }; 193 | EDA60A5A2317F43500B5FA3D /* GHWExtension */ = { 194 | isa = PBXGroup; 195 | children = ( 196 | EDC57714232E2EC100445D4F /* addImport */, 197 | EDBFBD1A231FF35500490C20 /* addComment */, 198 | ED6552322318FA500036A04A /* initView */, 199 | ED65522B2318F98E0036A04A /* addLazyCode */, 200 | ED6552342318FA720036A04A /* sortImport */, 201 | EDA60A702317F4BF00B5FA3D /* Tools */, 202 | ED65522A2318F98E0036A04A /* GHWExtensionConst.h */, 203 | EDA60A5B2317F43500B5FA3D /* SourceEditorExtension.h */, 204 | EDA60A5C2317F43500B5FA3D /* SourceEditorExtension.m */, 205 | EDA60A5E2317F43500B5FA3D /* SourceEditorCommand.h */, 206 | EDA60A5F2317F43500B5FA3D /* SourceEditorCommand.m */, 207 | EDA60A612317F43500B5FA3D /* Info.plist */, 208 | EDA60A622317F43500B5FA3D /* GHWExtension.entitlements */, 209 | ); 210 | path = GHWExtension; 211 | sourceTree = ""; 212 | }; 213 | EDA60A702317F4BF00B5FA3D /* Tools */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | EDA60A712317F4BF00B5FA3D /* NSString+Extension.h */, 217 | EDA60A722317F4BF00B5FA3D /* NSString+Extension.m */, 218 | ED65523E23190CE00036A04A /* NSMutableArray+GHWExtension.h */, 219 | ED65523F23190CE00036A04A /* NSMutableArray+GHWExtension.m */, 220 | ); 221 | path = Tools; 222 | sourceTree = ""; 223 | }; 224 | EDBFBD1A231FF35500490C20 /* addComment */ = { 225 | isa = PBXGroup; 226 | children = ( 227 | EDBFBD1B231FF38000490C20 /* GHWAddCommentManager.h */, 228 | EDBFBD1C231FF38000490C20 /* GHWAddCommentManager.m */, 229 | ); 230 | path = addComment; 231 | sourceTree = ""; 232 | }; 233 | EDC57714232E2EC100445D4F /* addImport */ = { 234 | isa = PBXGroup; 235 | children = ( 236 | EDC57715232E2EEB00445D4F /* GHWAddImportManager.h */, 237 | EDC57716232E2EEB00445D4F /* GHWAddImportManager.m */, 238 | ); 239 | path = addImport; 240 | sourceTree = ""; 241 | }; 242 | /* End PBXGroup section */ 243 | 244 | /* Begin PBXNativeTarget section */ 245 | EDA60A3A2317F41000B5FA3D /* GHWXcodeExtension */ = { 246 | isa = PBXNativeTarget; 247 | buildConfigurationList = EDA60A4F2317F41000B5FA3D /* Build configuration list for PBXNativeTarget "GHWXcodeExtension" */; 248 | buildPhases = ( 249 | EDA60A372317F41000B5FA3D /* Sources */, 250 | EDA60A382317F41000B5FA3D /* Frameworks */, 251 | EDA60A392317F41000B5FA3D /* Resources */, 252 | EDA60A692317F43500B5FA3D /* Embed App Extensions */, 253 | ); 254 | buildRules = ( 255 | ); 256 | dependencies = ( 257 | EDA60A642317F43500B5FA3D /* PBXTargetDependency */, 258 | ); 259 | name = GHWXcodeExtension; 260 | productName = GHWXcodeExtension; 261 | productReference = EDA60A3B2317F41000B5FA3D /* GHWXcodeExtension.app */; 262 | productType = "com.apple.product-type.application"; 263 | }; 264 | EDA60A552317F43500B5FA3D /* GHWExtension */ = { 265 | isa = PBXNativeTarget; 266 | buildConfigurationList = EDA60A662317F43500B5FA3D /* Build configuration list for PBXNativeTarget "GHWExtension" */; 267 | buildPhases = ( 268 | EDA60A522317F43500B5FA3D /* Sources */, 269 | EDA60A532317F43500B5FA3D /* Frameworks */, 270 | EDA60A542317F43500B5FA3D /* Resources */, 271 | EDAB4AE125F3D0D900342C7A /* Embed Frameworks */, 272 | ); 273 | buildRules = ( 274 | ); 275 | dependencies = ( 276 | ); 277 | name = GHWExtension; 278 | productName = GHWExtension; 279 | productReference = EDA60A562317F43500B5FA3D /* GHWExtension.appex */; 280 | productType = "com.apple.product-type.xcode-extension"; 281 | }; 282 | /* End PBXNativeTarget section */ 283 | 284 | /* Begin PBXProject section */ 285 | EDA60A332317F41000B5FA3D /* Project object */ = { 286 | isa = PBXProject; 287 | attributes = { 288 | LastUpgradeCheck = 1020; 289 | ORGANIZATIONNAME = Jingyao; 290 | TargetAttributes = { 291 | EDA60A3A2317F41000B5FA3D = { 292 | CreatedOnToolsVersion = 10.2.1; 293 | }; 294 | EDA60A552317F43500B5FA3D = { 295 | CreatedOnToolsVersion = 10.2.1; 296 | }; 297 | }; 298 | }; 299 | buildConfigurationList = EDA60A362317F41000B5FA3D /* Build configuration list for PBXProject "GHWXcodeExtension" */; 300 | compatibilityVersion = "Xcode 9.3"; 301 | developmentRegion = en; 302 | hasScannedForEncodings = 0; 303 | knownRegions = ( 304 | en, 305 | Base, 306 | ); 307 | mainGroup = EDA60A322317F41000B5FA3D; 308 | productRefGroup = EDA60A3C2317F41000B5FA3D /* Products */; 309 | projectDirPath = ""; 310 | projectRoot = ""; 311 | targets = ( 312 | EDA60A3A2317F41000B5FA3D /* GHWXcodeExtension */, 313 | EDA60A552317F43500B5FA3D /* GHWExtension */, 314 | ); 315 | }; 316 | /* End PBXProject section */ 317 | 318 | /* Begin PBXResourcesBuildPhase section */ 319 | EDA60A392317F41000B5FA3D /* Resources */ = { 320 | isa = PBXResourcesBuildPhase; 321 | buildActionMask = 2147483647; 322 | files = ( 323 | EDA60A452317F41000B5FA3D /* Assets.xcassets in Resources */, 324 | EDA60A482317F41000B5FA3D /* Main.storyboard in Resources */, 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | }; 328 | EDA60A542317F43500B5FA3D /* Resources */ = { 329 | isa = PBXResourcesBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | }; 335 | /* End PBXResourcesBuildPhase section */ 336 | 337 | /* Begin PBXSourcesBuildPhase section */ 338 | EDA60A372317F41000B5FA3D /* Sources */ = { 339 | isa = PBXSourcesBuildPhase; 340 | buildActionMask = 2147483647; 341 | files = ( 342 | EDA60A432317F41000B5FA3D /* ViewController.m in Sources */, 343 | EDA60A4B2317F41000B5FA3D /* main.m in Sources */, 344 | EDA60A402317F41000B5FA3D /* AppDelegate.m in Sources */, 345 | ); 346 | runOnlyForDeploymentPostprocessing = 0; 347 | }; 348 | EDA60A522317F43500B5FA3D /* Sources */ = { 349 | isa = PBXSourcesBuildPhase; 350 | buildActionMask = 2147483647; 351 | files = ( 352 | EDA60A752317F4BF00B5FA3D /* NSString+Extension.m in Sources */, 353 | EDA60A5D2317F43500B5FA3D /* SourceEditorExtension.m in Sources */, 354 | ED6552302318F98E0036A04A /* GHWAddLazyCodeManager.m in Sources */, 355 | ED6552372318FB180036A04A /* GHWInitViewManager.m in Sources */, 356 | EDC57717232E2EEB00445D4F /* GHWAddImportManager.m in Sources */, 357 | EDA60A602317F43500B5FA3D /* SourceEditorCommand.m in Sources */, 358 | ED65523A2318FBB70036A04A /* GHWSortImportManager.m in Sources */, 359 | EDBFBD1D231FF38000490C20 /* GHWAddCommentManager.m in Sources */, 360 | ED65524023190CE00036A04A /* NSMutableArray+GHWExtension.m in Sources */, 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | }; 364 | /* End PBXSourcesBuildPhase section */ 365 | 366 | /* Begin PBXTargetDependency section */ 367 | EDA60A642317F43500B5FA3D /* PBXTargetDependency */ = { 368 | isa = PBXTargetDependency; 369 | target = EDA60A552317F43500B5FA3D /* GHWExtension */; 370 | targetProxy = EDA60A632317F43500B5FA3D /* PBXContainerItemProxy */; 371 | }; 372 | /* End PBXTargetDependency section */ 373 | 374 | /* Begin PBXVariantGroup section */ 375 | EDA60A462317F41000B5FA3D /* Main.storyboard */ = { 376 | isa = PBXVariantGroup; 377 | children = ( 378 | EDA60A472317F41000B5FA3D /* Base */, 379 | ); 380 | name = Main.storyboard; 381 | sourceTree = ""; 382 | }; 383 | /* End PBXVariantGroup section */ 384 | 385 | /* Begin XCBuildConfiguration section */ 386 | EDA60A4D2317F41000B5FA3D /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | ALWAYS_SEARCH_USER_PATHS = NO; 390 | CLANG_ANALYZER_NONNULL = YES; 391 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 392 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 393 | CLANG_CXX_LIBRARY = "libc++"; 394 | CLANG_ENABLE_MODULES = YES; 395 | CLANG_ENABLE_OBJC_ARC = YES; 396 | CLANG_ENABLE_OBJC_WEAK = YES; 397 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 398 | CLANG_WARN_BOOL_CONVERSION = YES; 399 | CLANG_WARN_COMMA = YES; 400 | CLANG_WARN_CONSTANT_CONVERSION = YES; 401 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 402 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 403 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 404 | CLANG_WARN_EMPTY_BODY = YES; 405 | CLANG_WARN_ENUM_CONVERSION = YES; 406 | CLANG_WARN_INFINITE_RECURSION = YES; 407 | CLANG_WARN_INT_CONVERSION = YES; 408 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 409 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 410 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 411 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 412 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 413 | CLANG_WARN_STRICT_PROTOTYPES = YES; 414 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 415 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 416 | CLANG_WARN_UNREACHABLE_CODE = YES; 417 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 418 | CODE_SIGN_IDENTITY = "Mac Developer"; 419 | COPY_PHASE_STRIP = NO; 420 | DEBUG_INFORMATION_FORMAT = dwarf; 421 | ENABLE_STRICT_OBJC_MSGSEND = YES; 422 | ENABLE_TESTABILITY = YES; 423 | GCC_C_LANGUAGE_STANDARD = gnu11; 424 | GCC_DYNAMIC_NO_PIC = NO; 425 | GCC_NO_COMMON_BLOCKS = YES; 426 | GCC_OPTIMIZATION_LEVEL = 0; 427 | GCC_PREPROCESSOR_DEFINITIONS = ( 428 | "DEBUG=1", 429 | "$(inherited)", 430 | ); 431 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 432 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 433 | GCC_WARN_UNDECLARED_SELECTOR = YES; 434 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 435 | GCC_WARN_UNUSED_FUNCTION = YES; 436 | GCC_WARN_UNUSED_VARIABLE = YES; 437 | MACOSX_DEPLOYMENT_TARGET = 10.14; 438 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 439 | MTL_FAST_MATH = YES; 440 | ONLY_ACTIVE_ARCH = YES; 441 | SDKROOT = macosx; 442 | }; 443 | name = Debug; 444 | }; 445 | EDA60A4E2317F41000B5FA3D /* Release */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | ALWAYS_SEARCH_USER_PATHS = NO; 449 | CLANG_ANALYZER_NONNULL = YES; 450 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 451 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 452 | CLANG_CXX_LIBRARY = "libc++"; 453 | CLANG_ENABLE_MODULES = YES; 454 | CLANG_ENABLE_OBJC_ARC = YES; 455 | CLANG_ENABLE_OBJC_WEAK = YES; 456 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 457 | CLANG_WARN_BOOL_CONVERSION = YES; 458 | CLANG_WARN_COMMA = YES; 459 | CLANG_WARN_CONSTANT_CONVERSION = YES; 460 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 461 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 462 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 463 | CLANG_WARN_EMPTY_BODY = YES; 464 | CLANG_WARN_ENUM_CONVERSION = YES; 465 | CLANG_WARN_INFINITE_RECURSION = YES; 466 | CLANG_WARN_INT_CONVERSION = YES; 467 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 468 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 469 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 470 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 471 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 472 | CLANG_WARN_STRICT_PROTOTYPES = YES; 473 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 474 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 475 | CLANG_WARN_UNREACHABLE_CODE = YES; 476 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 477 | CODE_SIGN_IDENTITY = "Mac Developer"; 478 | COPY_PHASE_STRIP = NO; 479 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 480 | ENABLE_NS_ASSERTIONS = NO; 481 | ENABLE_STRICT_OBJC_MSGSEND = YES; 482 | GCC_C_LANGUAGE_STANDARD = gnu11; 483 | GCC_NO_COMMON_BLOCKS = YES; 484 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 485 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 486 | GCC_WARN_UNDECLARED_SELECTOR = YES; 487 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 488 | GCC_WARN_UNUSED_FUNCTION = YES; 489 | GCC_WARN_UNUSED_VARIABLE = YES; 490 | MACOSX_DEPLOYMENT_TARGET = 10.14; 491 | MTL_ENABLE_DEBUG_INFO = NO; 492 | MTL_FAST_MATH = YES; 493 | SDKROOT = macosx; 494 | }; 495 | name = Release; 496 | }; 497 | EDA60A502317F41000B5FA3D /* Debug */ = { 498 | isa = XCBuildConfiguration; 499 | buildSettings = { 500 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 501 | CODE_SIGN_ENTITLEMENTS = GHWXcodeExtension/GHWXcodeExtension.entitlements; 502 | CODE_SIGN_STYLE = Automatic; 503 | COMBINE_HIDPI_IMAGES = YES; 504 | DEVELOPMENT_TEAM = 45KX2E2Q3S; 505 | INFOPLIST_FILE = GHWXcodeExtension/Info.plist; 506 | LD_RUNPATH_SEARCH_PATHS = ( 507 | "$(inherited)", 508 | "@executable_path/../Frameworks", 509 | ); 510 | MACOSX_DEPLOYMENT_TARGET = 10.13; 511 | PRODUCT_BUNDLE_IDENTIFIER = com.jingyao.GHWXcodeExtension; 512 | PRODUCT_NAME = "$(TARGET_NAME)"; 513 | }; 514 | name = Debug; 515 | }; 516 | EDA60A512317F41000B5FA3D /* Release */ = { 517 | isa = XCBuildConfiguration; 518 | buildSettings = { 519 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 520 | CODE_SIGN_ENTITLEMENTS = GHWXcodeExtension/GHWXcodeExtension.entitlements; 521 | CODE_SIGN_STYLE = Automatic; 522 | COMBINE_HIDPI_IMAGES = YES; 523 | DEVELOPMENT_TEAM = 45KX2E2Q3S; 524 | INFOPLIST_FILE = GHWXcodeExtension/Info.plist; 525 | LD_RUNPATH_SEARCH_PATHS = ( 526 | "$(inherited)", 527 | "@executable_path/../Frameworks", 528 | ); 529 | MACOSX_DEPLOYMENT_TARGET = 10.13; 530 | PRODUCT_BUNDLE_IDENTIFIER = com.jingyao.GHWXcodeExtension; 531 | PRODUCT_NAME = "$(TARGET_NAME)"; 532 | }; 533 | name = Release; 534 | }; 535 | EDA60A672317F43500B5FA3D /* Debug */ = { 536 | isa = XCBuildConfiguration; 537 | buildSettings = { 538 | ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-2"; 539 | CODE_SIGN_ENTITLEMENTS = GHWExtension/GHWExtension.entitlements; 540 | CODE_SIGN_STYLE = Automatic; 541 | COMBINE_HIDPI_IMAGES = YES; 542 | DEVELOPMENT_TEAM = 45KX2E2Q3S; 543 | INFOPLIST_FILE = GHWExtension/Info.plist; 544 | LD_RUNPATH_SEARCH_PATHS = ( 545 | "$(inherited)", 546 | "@executable_path/../Frameworks", 547 | "@executable_path/../../../../Frameworks", 548 | ); 549 | MACOSX_DEPLOYMENT_TARGET = 10.13; 550 | PRODUCT_BUNDLE_IDENTIFIER = com.jingyao.GHWXcodeExtension.GHWExtension; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | SKIP_INSTALL = YES; 553 | }; 554 | name = Debug; 555 | }; 556 | EDA60A682317F43500B5FA3D /* Release */ = { 557 | isa = XCBuildConfiguration; 558 | buildSettings = { 559 | ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-2"; 560 | CODE_SIGN_ENTITLEMENTS = GHWExtension/GHWExtension.entitlements; 561 | CODE_SIGN_STYLE = Automatic; 562 | COMBINE_HIDPI_IMAGES = YES; 563 | DEVELOPMENT_TEAM = 45KX2E2Q3S; 564 | INFOPLIST_FILE = GHWExtension/Info.plist; 565 | LD_RUNPATH_SEARCH_PATHS = ( 566 | "$(inherited)", 567 | "@executable_path/../Frameworks", 568 | "@executable_path/../../../../Frameworks", 569 | ); 570 | MACOSX_DEPLOYMENT_TARGET = 10.13; 571 | PRODUCT_BUNDLE_IDENTIFIER = com.jingyao.GHWXcodeExtension.GHWExtension; 572 | PRODUCT_NAME = "$(TARGET_NAME)"; 573 | SKIP_INSTALL = YES; 574 | }; 575 | name = Release; 576 | }; 577 | /* End XCBuildConfiguration section */ 578 | 579 | /* Begin XCConfigurationList section */ 580 | EDA60A362317F41000B5FA3D /* Build configuration list for PBXProject "GHWXcodeExtension" */ = { 581 | isa = XCConfigurationList; 582 | buildConfigurations = ( 583 | EDA60A4D2317F41000B5FA3D /* Debug */, 584 | EDA60A4E2317F41000B5FA3D /* Release */, 585 | ); 586 | defaultConfigurationIsVisible = 0; 587 | defaultConfigurationName = Release; 588 | }; 589 | EDA60A4F2317F41000B5FA3D /* Build configuration list for PBXNativeTarget "GHWXcodeExtension" */ = { 590 | isa = XCConfigurationList; 591 | buildConfigurations = ( 592 | EDA60A502317F41000B5FA3D /* Debug */, 593 | EDA60A512317F41000B5FA3D /* Release */, 594 | ); 595 | defaultConfigurationIsVisible = 0; 596 | defaultConfigurationName = Release; 597 | }; 598 | EDA60A662317F43500B5FA3D /* Build configuration list for PBXNativeTarget "GHWExtension" */ = { 599 | isa = XCConfigurationList; 600 | buildConfigurations = ( 601 | EDA60A672317F43500B5FA3D /* Debug */, 602 | EDA60A682317F43500B5FA3D /* Release */, 603 | ); 604 | defaultConfigurationIsVisible = 0; 605 | defaultConfigurationName = Release; 606 | }; 607 | /* End XCConfigurationList section */ 608 | }; 609 | rootObject = EDA60A332317F41000B5FA3D /* Project object */; 610 | } 611 | -------------------------------------------------------------------------------- /GHWXcodeExtension.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GHWXcodeExtension.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GHWXcodeExtension.xcodeproj/xcshareddata/xcschemes/GHWExtension.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 16 | 22 | 23 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 70 | 73 | 74 | 75 | 81 | 82 | 83 | 84 | 85 | 86 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /GHWXcodeExtension.xcodeproj/xcshareddata/xcschemes/GHWXcodeExtension.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /GHWXcodeExtension.xcodeproj/xcuserdata/guohongwei719.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | GHWExtension.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | GHWXcodeExtension.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | EDA60A3A2317F41000B5FA3D 21 | 22 | primary 23 | 24 | 25 | EDA60A552317F43500B5FA3D 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /GHWXcodeExtension/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // GHWXcodeExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/29. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /GHWXcodeExtension/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // GHWXcodeExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/29. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 18 | // Insert code here to initialize your application 19 | } 20 | 21 | 22 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 23 | // Insert code here to tear down your application 24 | } 25 | 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /GHWXcodeExtension/Assets.xcassets/AppIcon-2.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /GHWXcodeExtension/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /GHWXcodeExtension/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /GHWXcodeExtension/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | Default 529 | 530 | 531 | 532 | 533 | 534 | 535 | Left to Right 536 | 537 | 538 | 539 | 540 | 541 | 542 | Right to Left 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | Default 554 | 555 | 556 | 557 | 558 | 559 | 560 | Left to Right 561 | 562 | 563 | 564 | 565 | 566 | 567 | Right to Left 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | -------------------------------------------------------------------------------- /GHWXcodeExtension/GHWXcodeExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /GHWXcodeExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2019 黑化肥发灰. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | 30 | 31 | -------------------------------------------------------------------------------- /GHWXcodeExtension/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // GHWXcodeExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/29. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : NSViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /GHWXcodeExtension/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // GHWXcodeExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/29. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @implementation ViewController 12 | 13 | - (void)viewDidLoad { 14 | [super viewDidLoad]; 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | 20 | - (void)setRepresentedObject:(id)representedObject { 21 | [super setRepresentedObject:representedObject]; 22 | 23 | // Update the view, if already loaded. 24 | } 25 | 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /GHWXcodeExtension/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // GHWXcodeExtension 4 | // 5 | // Created by 黑化肥发灰 on 2019/8/29. 6 | // Copyright © 2019 黑化肥发灰. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 一个好用的 Xcode 扩展:GHWXcodeExtension 2 | ### 目录 3 | 4 | [一. 前言](https://github.com/guohongwei719/GHWXcodeExtension#%E4%B8%80-%E5%89%8D%E8%A8%80) 5 | [二. 功能演示(注:均可配置快捷键,实现一键操作)](https://github.com/guohongwei719/GHWXcodeExtension#%E4%BA%8C-%E5%8A%9F%E8%83%BD%E6%BC%94%E7%A4%BA%E6%B3%A8%E5%9D%87%E5%8F%AF%E9%85%8D%E7%BD%AE%E5%BF%AB%E6%8D%B7%E9%94%AE%E5%AE%9E%E7%8E%B0%E4%B8%80%E9%94%AE%E6%93%8D%E4%BD%9C) 6 | [三. 安装配置方法](https://github.com/guohongwei719/GHWXcodeExtension#%E4%B8%89-%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95) 7 | [四. 使用注意事项](https://github.com/guohongwei719/GHWXcodeExtension#%E5%9B%9B-%E4%BD%BF%E7%94%A8%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9) 8 | [五. 调试 GHWXcodeExtension](https://github.com/guohongwei719/GHWXcodeExtension#%E4%BA%94-%E8%B0%83%E8%AF%95-ghwxcodeextension) 9 | [六. 后记](https://github.com/guohongwei719/GHWXcodeExtension#%E5%85%AD-%E5%90%8E%E8%AE%B0) 10 | 11 | ## 一. 前言 12 | 在 Xcode8 以前,开发者可以在 Xccode 运行时通过注入代码来实现插件的功能。插件可以在Alcatraz 上面提交和分发。不过 Xcode8 禁止了该方式的插件安装,转而向开发者提供了Xcode Source Editor Extension(以下简称 Extension)的方式来做插件。平时写代码过程中发现有很多代码都是重复的,属于无脑代码,而且团队协作中统一的代码格式规范非常重要,因此试图通过 Extension 解决这些问题,从而开发了这个工具。 13 | 14 | 实现的功能: 15 | 16 | 1. 初始化自定义view、UICollectionViewCell、UITableViewCell、viewController,自动删除无用代码和添加默认代码; 17 | 2. 为属性自动添加懒加载代码、对应协议声明和协议方法,主要有 UITableView\UICollectionView\UIScrollView\UIButton\UILabel\UIImageView; 18 | 3. 选中一个类,文件顶部自动添加对应的 import; 19 | 4. 给 import 分组排序去重,从上到下为 主类头文件、viewController、view、manager & logic、第三方库、model、category、其他。 20 | 21 | 22 | ## 二. 功能演示(注:均可配置快捷键,实现一键操作) 23 | #### 1. 初始化自定义view、UICollectionViewCell、UITableViewCell、viewController,自动删除无用代码和添加默认代码; 24 | 25 | ![(image)](https://github.com/guohongwei719/GHWXcodeExtension/blob/master/resources/initView.gif) 26 | 27 | 28 | #### 2. 为属性自动添加懒加载代码、对应协议声明和协议方法,主要有 UITableView\UICollectionView\UIScrollView\UIButton\UILabel\UIImageView; 29 | 30 | ![(image)](https://github.com/guohongwei719/GHWXcodeExtension/blob/master/resources/addLazyCode.gif) 31 | 32 | 注意:需要添加懒加载代码的属性需要被光标选中 33 | 34 | #### 3. 选中一个类,文件顶部自动添加对应的 import; 35 | 36 | ![(image)](https://github.com/guohongwei719/GHWXcodeExtension/blob/master/resources/addImport.gif) 37 | 38 | #### 4. 给 import 分组排序去重,从上到下为 主类头文件、viewController、view、manager & logic、第三方库、model、category、其他。 39 | 40 | ![(image)](https://github.com/guohongwei719/GHWXcodeExtension/blob/master/resources/sortImport.gif) 41 | 42 | 注意: 43 | 44 | 1. 如果不选中对应的 import 则默认是所有 import 行,如果选中的话则只会对选中的 import 分组排序去重 45 | 2. viewController 后缀小写必须为 "controller.h"、"vc.h"; 46 | 3. view 后缀小写必须为 "view.h"、"bar.h"、"cell.h"; 47 | 4. manager & logic 后缀小写必须为"manager.h"、"logic.h"、"helper.h"、"services.h"、"service.h"。 48 | 49 | ## 三. 安装配置方法 50 | #### 1. 将项目 clone 下来,如果不想 clone 项目,直接去 release 下面下载生成的 GHWXcodeExtension.zip,链接 [https://github.com/guohongwei719/GHWXcodeExtension/releases](https://github.com/guohongwei719/GHWXcodeExtension/releases),解压即可,然后跳到第三步,如下图 51 | ![](./resources/11.png) 52 | #### 2. 将 clone 的项目编译成功,到 Products 下,选择 GHWXcodeExtension.app 右键,选择 Show in Finder 53 | ![](./resources/6.png) 54 | 55 | #### 3. 将 GHWXcodeExtension 复制到应用程序下面,双击打开 56 | ![](./resources/7.png) 57 | #### 4. 到 系统偏好设置 找到 扩展,选择 Xcode Source Editor,选中 GHWExtension 58 | ![](./resources/8.png) 59 | ![](./resources/9.png) 60 | 61 | #### 5. 打开项目以后,可以在 Xcode 菜单栏,选择 Editor, 可以看到 GHWExtension 出现在最下面 62 | ![](./resources/4.png) 63 | 64 | #### 6. 选择 GHWExtension,出现可以使用的功能选项,顾名思义 65 | ![](./resources/5.png) 66 | 67 | #### 7. 四个功能选项都可以配置快捷键,实现一键操作,推荐分别设置为 option+z\option+x\option+c\option+v,如下图 68 | ![](./resources/10.png) 69 | 70 | ## 四. 使用注意事项 71 | #### 1. 使用 addLazyCode 功能的时候,如果添加了代码后想撤销,使用 command + z,这时候 Xcode 可能会 crash,这应该是 Xcode 本身的一个 bug,所以需要注意一下,正常情况下添加以后也不会撤销,如果要撤销手动删除也很方便,即使 crash 了再打开就行了,打开以后是删除状态。希望苹果能尽快修复这个 bug。 72 | 73 | ## 五. 调试 GHWXcodeExtension 74 | #### 1. 选择 GHWExtension scheme 75 | ![](./resources/1.png) 76 | 77 | #### 2. 运行,选择 xcode,点击 run 78 | ![](./resources/2.png) 79 | 80 | #### 3. 选择一个项目 81 | ![](./resources/3.png) 82 | 83 | ## 六. 后记 84 | 欢迎提 bug 和 feature。 85 | 微博:[黑化肥发灰11](https://weibo.com/u/2977255324) 86 | 简书地址:[https://www.jianshu.com/u/fb5591dbd1bf](https://www.jianshu.com/u/fb5591dbd1bf) 87 | 掘金地址:[https://juejin.im/user/595b50896fb9a06ba82d14d4](https://juejin.im/user/595b50896fb9a06ba82d14d4) 88 | -------------------------------------------------------------------------------- /resources/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/01.png -------------------------------------------------------------------------------- /resources/010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/010.png -------------------------------------------------------------------------------- /resources/011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/011.png -------------------------------------------------------------------------------- /resources/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/02.png -------------------------------------------------------------------------------- /resources/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/03.png -------------------------------------------------------------------------------- /resources/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/04.png -------------------------------------------------------------------------------- /resources/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/05.png -------------------------------------------------------------------------------- /resources/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/06.png -------------------------------------------------------------------------------- /resources/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/07.png -------------------------------------------------------------------------------- /resources/08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/08.png -------------------------------------------------------------------------------- /resources/09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/09.png -------------------------------------------------------------------------------- /resources/0addImport.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/0addImport.gif -------------------------------------------------------------------------------- /resources/0addLazyCode.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/0addLazyCode.gif -------------------------------------------------------------------------------- /resources/0initView.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/0initView.gif -------------------------------------------------------------------------------- /resources/0sortImport.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guohongwei719/GHWXcodeExtension/e0f926d44eee36d825be00fabfe08fdc88c0abf1/resources/0sortImport.gif --------------------------------------------------------------------------------