-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
1,836 additions
and
943 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
CleanHeaders-Xcode-Extension/CleanHeaders_Xcode_Extension.entitlements
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>com.apple.security.app-sandbox</key> | ||
<true/> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>CFBundleDevelopmentRegion</key> | ||
<string>en</string> | ||
<key>CFBundleDisplayName</key> | ||
<string>Sort Headers</string> | ||
<key>CFBundleExecutable</key> | ||
<string>$(EXECUTABLE_NAME)</string> | ||
<key>CFBundleIdentifier</key> | ||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
<key>CFBundleInfoDictionaryVersion</key> | ||
<string>6.0</string> | ||
<key>CFBundleName</key> | ||
<string>$(PRODUCT_NAME)</string> | ||
<key>CFBundlePackageType</key> | ||
<string>XPC!</string> | ||
<key>CFBundleShortVersionString</key> | ||
<string>1.0</string> | ||
<key>CFBundleVersion</key> | ||
<string>1</string> | ||
<key>LSMinimumSystemVersion</key> | ||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string> | ||
<key>NSExtension</key> | ||
<dict> | ||
<key>NSExtensionAttributes</key> | ||
<dict> | ||
<key>XCSourceEditorCommandDefinitions</key> | ||
<array> | ||
<dict> | ||
<key>XCSourceEditorCommandClassName</key> | ||
<string>SourceEditorCommand</string> | ||
<key>XCSourceEditorCommandIdentifier</key> | ||
<string>com.karthik.cleanHeader-Xcode</string> | ||
<key>XCSourceEditorCommandName</key> | ||
<string>Sort Headers</string> | ||
</dict> | ||
</array> | ||
<key>XCSourceEditorExtensionPrincipalClass</key> | ||
<string>SourceEditorExtension</string> | ||
</dict> | ||
<key>NSExtensionPointIdentifier</key> | ||
<string>com.apple.dt.Xcode.extension.source-editor</string> | ||
</dict> | ||
<key>NSHumanReadableCopyright</key> | ||
<string>Copyright © 2016 Karthik. All rights reserved.</string> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// | ||
// SortHeader.h | ||
// CleanHeaders-Xcode | ||
// | ||
// Created by Karthik on 28/10/2016. | ||
// Copyright © 2016 Karthik. All rights reserved. | ||
// | ||
|
||
#import <XcodeKit/XcodeKit.h> | ||
|
||
static inline NSArray *formatSelectionLines(NSArray *sourceLines) { | ||
|
||
NSMutableArray *lines = [[NSMutableArray alloc] initWithArray:sourceLines]; | ||
|
||
// Let's assume all header files start with an #import, #include, @import, | ||
// import. | ||
NSString *traditionalImportPrefix = @"#import"; | ||
NSString *frameworkImportPrefix = @"@import"; | ||
NSString *traditionalIncludePrefix = @"#include"; | ||
NSString *swiftPrefix = @"import"; | ||
|
||
// Position of the first and last line of header, to be used for repalcement | ||
// of header content. | ||
NSInteger __block initalIndex = -1; | ||
NSInteger __block lastIndex = -1; | ||
BOOL __block endOfFileWithNewLine = YES; // Indicates if the selection's last | ||
// line was a new line. | ||
NSMutableArray *headerRows = [[NSMutableArray alloc] init]; | ||
|
||
// Go through each of the line and identify any header elements. | ||
[lines enumerateObjectsUsingBlock:^(NSString *string, NSUInteger idx, | ||
BOOL *_Nonnull stop) { | ||
NSString *cleansedLine = | ||
[string stringByTrimmingCharactersInSet: | ||
[NSCharacterSet whitespaceAndNewlineCharacterSet]]; | ||
|
||
BOOL isLineHeader = [cleansedLine hasPrefix:traditionalImportPrefix] || | ||
[cleansedLine hasPrefix:traditionalIncludePrefix] || | ||
[cleansedLine hasPrefix:frameworkImportPrefix] || | ||
[cleansedLine hasPrefix:swiftPrefix]; | ||
|
||
// If the line is a header and no header element has been detected so far, | ||
// mark this as the start of the header segment. | ||
if (isLineHeader && initalIndex < 0) { | ||
initalIndex = idx; | ||
} else if (initalIndex >= 0 && !(isLineHeader || ![cleansedLine length])) { | ||
// If the inital index has been set AND the line is not a header or a new | ||
// line, then this is to be marked as the end of header segment and | ||
// enumeration has to be stopped. | ||
lastIndex = idx; | ||
*stop = YES; | ||
} | ||
|
||
if (initalIndex >= 0 && lastIndex < 0) { | ||
// If the inital index is already set and we are in this condition it | ||
// means we are parsing the header. Check for duplicates and ensure that | ||
// it is not a new line and then add to the header rows array. | ||
if (![headerRows containsObject:[cleansedLine stringByAppendingString:@"\n"]] && | ||
[cleansedLine length]) { | ||
cleansedLine = [cleansedLine stringByAppendingString:@"\n"]; | ||
[headerRows addObject:cleansedLine]; | ||
} | ||
} | ||
|
||
// Reached the end of the selection or a file. (In case of a selection or a | ||
// header only file) | ||
if (idx >= lines.count - 1) { | ||
lastIndex = idx + 1; | ||
|
||
// If the end was a header and not a new line and also marked the end of | ||
// selection, a new line would look odd. | ||
if ([cleansedLine length]) { | ||
endOfFileWithNewLine = NO; | ||
} | ||
} | ||
}]; | ||
|
||
// If both the indices are set it means that we have a header section in the | ||
// file and it needs replacing after sorting. | ||
if (lastIndex >= 0 && initalIndex >= 0) { | ||
[headerRows sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; | ||
// Add a new line to make it look clean (if needed, if only header is selected then don't) | ||
// This is a flawed logic, but cannot think of a perfect way to do it right now. | ||
if (endOfFileWithNewLine && !(headerRows.count == lines.count)) { | ||
[headerRows addObject:@"\n"]; | ||
} else if((headerRows.count == lines.count) && headerRows.count) { | ||
// Avoid extra line if one selects only the header and keeps sorting them. | ||
NSString *lastHeader = [headerRows lastObject]; | ||
lastHeader = [lastHeader stringByReplacingOccurrencesOfString:@"\n" withString:@""]; | ||
[headerRows replaceObjectAtIndex:headerRows.count - 1 withObject:lastHeader]; | ||
} | ||
// replace it in the array of all lines. | ||
[lines replaceObjectsInRange:NSMakeRange(initalIndex, | ||
(lastIndex - initalIndex)) | ||
withObjectsFromArray:headerRows]; | ||
} | ||
|
||
return lines; | ||
} | ||
|
||
static inline NSString *formatSelection(NSString *content) { | ||
|
||
// Convert the entire source into an array based on new lines. | ||
// Hence the imports have to be alteast in new line to work. | ||
return [formatSelectionLines([content componentsSeparatedByString:@"\n"]) | ||
componentsJoinedByString:@""]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// | ||
// SourceEditorCommand.h | ||
// CleanHeaders-Xcode-Extension | ||
// | ||
// Created by Karthik on 28/10/2016. | ||
// Copyright © 2016 Karthik. All rights reserved. | ||
// | ||
|
||
#import <XcodeKit/XcodeKit.h> | ||
|
||
@interface SourceEditorCommand : NSObject <XCSourceEditorCommand> | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// | ||
// SourceEditorCommand.m | ||
// CleanHeaders-Xcode-Extension | ||
// | ||
// Created by Karthik on 28/10/2016. | ||
// Copyright © 2016 Karthik. All rights reserved. | ||
// | ||
|
||
#import "SourceEditorCommand.h" | ||
#import "SortHeader.h" | ||
#import "xTextModifier.h" | ||
|
||
@implementation SourceEditorCommand | ||
|
||
- (void)performCommandWithInvocation:(XCSourceEditorCommandInvocation *)invocation | ||
completionHandler:(void (^)(NSError * _Nullable nilOrError))completionHandler { | ||
[xTextModifier select:invocation | ||
handler:self.handlers[invocation.commandIdentifier] | ||
handlerForAllContent:self.handlers[@"all_source"]]; | ||
completionHandler(nil); | ||
} | ||
|
||
- (NSDictionary *)handlers { | ||
static NSDictionary *_instance; | ||
static dispatch_once_t onceToken; | ||
dispatch_once(&onceToken, ^{ | ||
_instance = @{ | ||
@"com.karthik.cleanHeader-Xcode": | ||
^NSString *(NSString *text) { return formatSelection(text); }, | ||
@"all_source": | ||
^NSArray *(NSArray *lines) { return formatSelectionLines(lines); } | ||
}; | ||
}); | ||
return _instance; | ||
} | ||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// | ||
// SourceEditorExtension.h | ||
// CleanHeaders-Xcode-Extension | ||
// | ||
// Created by Karthik on 28/10/2016. | ||
// Copyright © 2016 Karthik. All rights reserved. | ||
// | ||
|
||
#import <XcodeKit/XcodeKit.h> | ||
|
||
@interface SourceEditorExtension : NSObject <XCSourceEditorExtension> | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// | ||
// SourceEditorExtension.m | ||
// CleanHeaders-Xcode-Extension | ||
// | ||
// Created by Karthik on 28/10/2016. | ||
// Copyright © 2016 Karthik. All rights reserved. | ||
// | ||
|
||
#import "SourceEditorExtension.h" | ||
|
||
@implementation SourceEditorExtension | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// | ||
// xTextMatcher.h | ||
// xTextHandler | ||
// | ||
// Created by cyan on 16/6/18. | ||
// Copyright © 2016年 cyan. All rights reserved. | ||
// | ||
|
||
#import <XcodeKit/XcodeKit.h> | ||
|
||
static NSString *const xTextHandlerStringPattern = @"\"(.+)\""; // match "abc" | ||
static NSString *const xTextHandlerHexPattern = @"([0-9a-fA-F]+)"; // match 00FFFF | ||
static NSString *const xTextHandlerRGBPattern = @"([0-9]+.+[0-9]+.+[0-9]+)"; // match 20, 20, 20 | 20 20 20 ... | ||
static NSString *const xTextHandlerRadixPattern = @"([0-9]+)"; // match numbers | ||
|
||
@interface xTextMatchResult : NSObject | ||
|
||
@property (nonatomic, copy) NSString *text; // text for each lines | ||
@property (nonatomic, assign) NSRange range; // clipped text range | ||
@property (nonatomic, assign) BOOL clipboard; // is clipboard text | ||
|
||
|
||
/** | ||
Result from clipboard text | ||
@return xTextMatchResult | ||
*/ | ||
+ (instancetype)clipboardResult; | ||
|
||
/** | ||
Result with text & clipped text | ||
@param text text | ||
@param clipped clipped text | ||
@return xTextMatchResult | ||
*/ | ||
+ (instancetype)resultWithText:(NSString *)text clipped:(NSString *)clipped; | ||
|
||
@end | ||
|
||
@interface xTextMatcher : NSObject | ||
|
||
|
||
/** | ||
Match texts in XCSourceEditorCommandInvocation | ||
@param selection XCSourceTextRange | ||
@param invocation XCSourceEditorCommandInvocation | ||
@return match result | ||
*/ | ||
+ (xTextMatchResult *)match:(XCSourceTextRange *)selection invocation:(XCSourceEditorCommandInvocation *)invocation; | ||
|
||
@end |
Oops, something went wrong.