├── .gitignore ├── Design └── XAlign.sketch ├── LICENSE ├── README.md ├── Source ├── NSString+XAlign.h ├── NSString+XAlign.m ├── Patterns.bundle │ └── default.plist ├── XAlignPattern.h └── XAlignPattern.m ├── SourceEditorExtension ├── Info.plist ├── SourceEditorCommand.h ├── SourceEditorCommand.m ├── SourceEditorExtension.entitlements ├── SourceEditorExtension.h └── SourceEditorExtension.m ├── XAlign.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata └── XAlign ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets └── AppIcon.appiconset │ ├── 1024.png │ ├── 1024@0.25x.png │ ├── 1024@0.5x-1.png │ ├── 1024@0.5x.png │ └── Contents.json ├── Base.lproj └── Main.storyboard ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | xcuserdata 12 | profile 13 | *.moved-aside 14 | DerivedData 15 | .idea/ 16 | *.hmap 17 | *.xccheckout 18 | 19 | #CocoaPods 20 | Pods 21 | 22 | /video/ 23 | /video 24 | /ignore 25 | -------------------------------------------------------------------------------- /Design/XAlign.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qfish/XAlign/1513631193d062c7036fce0538eee07edc08e409/Design/XAlign.sketch -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 QFisH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | XAlign (Ready for Xcode 8+ 🚀) 2 | ====== 3 | 4 | An amazing Xcode Source Editor extension to align regular code. It can align anything by using custom alignment patterns. 5 | 6 | ## What's XAlign 7 | 8 | Here are some example alignment patterns. Of course you can make your own. The pattern file is here: `/Source/Patterns.bundle/default.plist`, and the patterns are based on regular expression. 9 | 10 | **Tips**: 11 | 12 | * _You may not like the alignment style below, **try it yourself** or **tell me at the [Issues](https://github.com/qfish/XAlign/issues?state=open)**._ :) 13 | * There is no need to align all codes at a time when they are complicated, try to align by group which the codes are more similar in. 14 | * 对齐不需要一次全部对齐,可以分组多对几次,那些等号差的太远的就别让它参与对齐了。 15 | * 默认对齐的风格不是你喜欢的,可以自定义,或者提个 [Issues](https://github.com/qfish/XAlign/issues?state=open)。 16 | 17 | ### Align by equals sign 18 | ![Equal](http://qfi.sh/XAlign/images/equal.gif) 19 | 20 | ### Align by define group 21 | ![Define](http://qfi.sh/XAlign/images/define.gif) 22 | 23 | ### Align by property group 24 | ![Property](http://qfi.sh/XAlign/images/property.gif) 25 | 26 | ### Todo: 27 | 28 | - [x] Much easier to customize alignment patterns. 29 | 30 | ## Install on Xcode 8 31 | 1. Download the [XAlign.dmg📎](https://github.com/qfish/XAlign/releases/download/v1.0/XAlign.1.0.dmg) or [XAlign.app.zip📎](https://github.com/qfish/XAlign/releases/download/v1.0/XAlign.app.zip) 32 | 2. Open and copy `XAlign.app` to `/Applications` folder 33 | 3. Run it then close it. 34 | 35 | ## Usage 36 | ### 1. Enable XAlign 37 | Check System Preferences -> Extensions -> Xocde Source Editor -> XAlign 38 | 39 | ![help-1](https://cloud.githubusercontent.com/assets/679824/20145614/b86f6742-a6db-11e6-846b-771447ec0933.png) 40 | 41 | ### 2. Setting Shortcut in Xocde 42 | Preferences -> Key bindings -> Filter: xalign 43 | 44 | ![help-2](https://cloud.githubusercontent.com/assets/679824/20146079/735244ca-a6dd-11e6-83a9-069fd489b0f6.png) 45 | 46 | ## Trouble Shooting 47 | * Please install macOS Sierra (version 10.12) if your macOS is 10.11. 48 | * If you are looking for the version supporting Xcode 7, check this [branch](https://github.com/qfish/XAlign/tree/Xcode%3C8); 49 | 50 | ## Want to help 51 | 52 | * [Star this repository](https://github.com/qfish/XAlign/) 53 | * [Bug report & Advice](https://github.com/qfish/XAlign/issues) 54 | * [Fork & Pull Request](https://github.com/qfish/XAlign/pulls) 55 | 56 | ## Special thanks to 57 | 58 | * Geek Zoo Studio Geek Zoo Studio 59 | 60 | They provide awesome design and development works continues to help the open-source community even better. 61 | 62 | 63 | * [BeeFramework](https://github.com/gavinkwoe/BeeFramework) 64 | 65 | BeeFramework is a new generation of development framework which makes faster and easier app development, Build your app by geek's way. 66 | -------------------------------------------------------------------------------- /Source/NSString+XAlign.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+XAlign2.h 3 | // main 4 | // 5 | // Created by QFish on 11/18/13. 6 | // Copyright (c) 2013 net.qfish. All rights reserved. 7 | // 8 | 9 | #ifdef __XALIGN__ 10 | #import "SharedXcode.h" 11 | #define kTabSize [SharedXcode tabWidth] 12 | #else 13 | #define kTabSize 4 14 | #endif 15 | 16 | #import "XAlignPattern.h" 17 | 18 | @interface NSString (XAlign) 19 | - (NSString *)xtrim; 20 | - (NSString *)xtrimTail; 21 | - (NSUInteger)xlength; 22 | - (NSString *)stringByAligningWithPatterns:(NSArray *)patterns; 23 | - (NSString *)stringByAligningWithPatterns:(NSArray *)patterns partialCount:(NSUInteger)count; 24 | - (NSArray *)componentsSeparatedByRegexPattern:(NSString *)pattern position:(XAlignPosition)position match:(NSString **)match; 25 | @end 26 | -------------------------------------------------------------------------------- /Source/NSString+XAlign.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+XAlign2.m 3 | // main 4 | // 5 | // Created by QFish on 11/18/13. 6 | // Copyright (c) 2013 net.qfish. All rights reserved. 7 | // 8 | 9 | #import "NSString+XAlign.h" 10 | 11 | #undef ____STEP_IIN 12 | #define ____STEP_IIN(s) 13 | #undef ____STEP_OUT 14 | #define ____STEP_OUT(s) 15 | 16 | @interface XAlignLine : NSObject 17 | @property (nonatomic, retain) NSMutableArray * partials; 18 | + (id)line; 19 | - (NSString *)stringWithPaddings:(NSArray *)paddings patterns:(NSArray *)patterns; 20 | @end 21 | 22 | @implementation XAlignLine 23 | 24 | + (id)line 25 | { 26 | return [[self alloc] init]; 27 | } 28 | 29 | - (id)init 30 | { 31 | self = [super init]; 32 | 33 | if ( self ) 34 | { 35 | self.partials = [NSMutableArray array]; 36 | } 37 | 38 | return self; 39 | } 40 | 41 | - (int)sumOfPaddings:(NSArray *)paddings atRange:(NSRange)range 42 | { 43 | int sum = 0; 44 | 45 | if ( NSMaxRange(range) > paddings.count ) 46 | return 0; 47 | 48 | for ( NSUInteger i=range.location, j=1; j<=range.length; j++, i++) 49 | { 50 | sum += [paddings[i] intValue]; 51 | } 52 | 53 | return sum; 54 | } 55 | 56 | - (NSString *)stringWithPaddings:(NSArray *)paddings patterns:(NSArray *)patterns 57 | { 58 | NSMutableString * string = [NSMutableString string]; 59 | 60 | for ( int i=0; i < self.partials.count; i++ ) 61 | { 62 | NSString * partial = self.partials[i]; 63 | NSUInteger padding = [paddings[i] integerValue]; 64 | NSString * tempString = nil; 65 | 66 | if ( partial.length ) 67 | { 68 | /* 69 | i: 0 1 2 3 4 5 6 7 8 9 10 70 | ----- --- --- --- ---- 71 | p: 0 1 2 3 4 72 | */ 73 | 74 | NSUInteger pIndex = i == 0 ? 0 : ( ( i + 1 ) / 2 - 1 ); 75 | 76 | XAlignPattern * pattern = patterns[pIndex]; 77 | 78 | // build string 79 | 80 | if ( 0 == i ) 81 | { 82 | if ( XAlignPaddingModeNone == pattern.headMode ) 83 | tempString = partial; 84 | else 85 | tempString = [partial stringByPaddingToLength:padding withString:@" " startingAtIndex:0]; 86 | } 87 | else 88 | { 89 | switch ( i % 2 ) 90 | { 91 | case 0: // tail 92 | if ( XAlignPaddingModeNone == pattern.tailMode ) 93 | tempString = partial; 94 | else 95 | tempString = [partial stringByPaddingToLength:padding withString:@" " startingAtIndex:0]; 96 | break; 97 | case 1: // match 98 | tempString = pattern.control(padding, partial); 99 | break; 100 | } 101 | } 102 | } 103 | else 104 | { 105 | tempString = @""; 106 | } 107 | 108 | [string appendString:tempString]; 109 | } 110 | 111 | return string.xtrimTail; 112 | } 113 | 114 | - (NSString *)description 115 | { 116 | return [self.partials description]; 117 | } 118 | @end 119 | 120 | #pragma mark - 121 | 122 | @implementation NSString (XAlign) 123 | 124 | - (NSString *)xtrim 125 | { 126 | return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 127 | } 128 | 129 | - (NSString *)xtrimTail 130 | { 131 | NSError * error = nil; 132 | NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:@"\\s+$" options:NSRegularExpressionCaseInsensitive error:&error]; 133 | 134 | if ( error ) 135 | return self; 136 | 137 | NSArray * matches = [regex matchesInString:self options:NSMatchingReportProgress range:NSMakeRange(0, self.length)]; 138 | 139 | if ( 0 == matches.count ) 140 | return self; 141 | 142 | return [self substringWithRange:NSMakeRange(0, [matches[0] range].location)]; 143 | } 144 | 145 | - (NSUInteger)xlength 146 | { 147 | return [self lengthWithTabWidth:kTabSize]; 148 | } 149 | 150 | - (NSUInteger)lengthWithTabWidth:(NSUInteger)tabWidth 151 | { 152 | const char * c = self.UTF8String; 153 | 154 | int count = 0; 155 | 156 | while ( *c ) 157 | { 158 | if ( *c == '\t' ) 159 | count += tabWidth; 160 | else 161 | count++; 162 | c++; 163 | } 164 | 165 | return count; 166 | } 167 | 168 | - (NSString *)stringByAligningWithPatterns:(NSArray *)patterns 169 | { 170 | return [self stringByAligningWithPatterns:patterns partialCount:(patterns.count * 2 + 1)]; 171 | } 172 | 173 | - (NSString *)stringByAligningWithPatterns:(NSArray *)patterns partialCount:(NSUInteger)partialCount 174 | { 175 | NSArray * lines = [self componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; 176 | 177 | if ( lines.count <= 1 ) 178 | return self; 179 | 180 | NSMutableArray * paddings = [NSMutableArray array]; 181 | NSMutableArray * processLines = [NSMutableArray array]; 182 | 183 | for ( int j=0; j < partialCount; j++ ) 184 | { 185 | [paddings addObject:@(-1)]; 186 | } 187 | 188 | for ( NSString * line in lines ) 189 | { 190 | NSString * trimLine = line.xtrimTail; 191 | 192 | XAlignLine * xline = nil; 193 | 194 | [trimLine processLine:&xline level:(int)(patterns.count - 1) patterns:patterns paddings:paddings]; 195 | 196 | if ( !xline ) 197 | { 198 | [processLines addObject:trimLine]; 199 | } 200 | else 201 | { 202 | [processLines addObject:xline]; 203 | } 204 | } 205 | 206 | NSMutableString * newLines = [NSMutableString string]; 207 | 208 | for ( int i=0; i < processLines.count; i++ ) 209 | { 210 | id line = processLines[i]; 211 | 212 | if ( [line isKindOfClass:[NSString class]] ) 213 | { 214 | [newLines appendString:line]; 215 | } 216 | else if ( [line isKindOfClass:[XAlignLine class]] ) 217 | { 218 | [newLines appendString:[line stringWithPaddings:paddings patterns:patterns]]; 219 | } 220 | 221 | if ( i != processLines.count - 1 ) 222 | { 223 | [newLines appendString:@"\n"]; 224 | } 225 | } 226 | 227 | return newLines; 228 | } 229 | 230 | - (void)processLine:(XAlignLine **)line level:(int)level patterns:(NSArray *)patterns paddings:(NSMutableArray *)paddings 231 | { 232 | if ( level < 0 ) 233 | return; 234 | 235 | XAlignPattern * pattern = patterns[level]; 236 | 237 | NSString * match = nil; 238 | NSArray * components = [self componentsSeparatedByRegexPattern:pattern.string position:pattern.position match:&match]; 239 | 240 | if ( !match ) 241 | { 242 | if ( !pattern.isOptional ) 243 | { 244 | *line = nil; 245 | return; 246 | } 247 | else 248 | { 249 | components = @[ self, @"" ]; 250 | match = @""; 251 | } 252 | } 253 | 254 | if ( nil == *line ) 255 | *line = [XAlignLine line]; 256 | 257 | XAlignLine * xline = *line; 258 | 259 | NSString * head = [components firstObject]; 260 | NSString * tail = [components lastObject]; 261 | 262 | [head processLine:line level:(level-1) patterns:patterns paddings:paddings]; 263 | 264 | ____STEP_IIN( head ) 265 | if ( 0 == level && head ) 266 | { 267 | // add head partial 268 | [xline.partials addObject:head]; 269 | // get index for match padding 270 | NSInteger headIndex = level; 271 | NSInteger headPadding = [paddings[headIndex] integerValue]; 272 | NSInteger newMatchPadding = head.xlength; 273 | switch ( pattern.headMode ) 274 | { 275 | case XAlignPaddingModeMin: 276 | { 277 | headPadding = headPadding == -1 ? NSNotFound : headPadding; 278 | paddings[headIndex] = @( MIN( headPadding , newMatchPadding ) ); 279 | } 280 | break; 281 | case XAlignPaddingModeMax: 282 | { 283 | headPadding = headPadding == -1 ? -1 : headPadding; 284 | paddings[headIndex] = @( MAX( headPadding , newMatchPadding ) ); 285 | } 286 | break; 287 | default: 288 | paddings[headIndex] = @( newMatchPadding ); 289 | break; 290 | } 291 | } 292 | ____STEP_OUT( head ) 293 | 294 | ____STEP_IIN( match ) 295 | // add match partial 296 | [xline.partials addObject:match]; 297 | // get index for match padding 298 | NSInteger matchIndex = level * 2 + 1; 299 | NSInteger matchPadding = [paddings[matchIndex] integerValue]; 300 | NSInteger newMatchPadding = match.xlength; 301 | switch ( pattern.matchMode ) 302 | { 303 | case XAlignPaddingModeMin: 304 | { 305 | matchPadding = matchPadding == -1 ? NSNotFound : matchPadding; 306 | paddings[matchIndex] = @( MIN( matchPadding , newMatchPadding ) ); 307 | } 308 | break; 309 | case XAlignPaddingModeMax: 310 | { 311 | matchPadding = matchPadding == -1 ? -1 : matchPadding; 312 | paddings[matchIndex] = @( MAX( matchPadding , newMatchPadding ) ); 313 | } 314 | break; 315 | default: 316 | paddings[matchIndex] = @( newMatchPadding ); 317 | break; 318 | } 319 | ____STEP_OUT( match ) 320 | 321 | ____STEP_IIN( tail ) 322 | // add tail partial 323 | [xline.partials addObject:tail]; 324 | // get index for match padding 325 | NSInteger tailIndex = level * 2 + 2; 326 | NSInteger tailPadding = [paddings[tailIndex] integerValue]; 327 | NSInteger newTailPadding = tail.xlength; 328 | switch ( pattern.tailMode ) 329 | { 330 | case XAlignPaddingModeMin: 331 | { 332 | tailPadding = tailPadding == -1 ? NSNotFound : tailPadding; 333 | paddings[tailIndex] = @( MIN( tailPadding , newTailPadding ) ); 334 | } 335 | break; 336 | case XAlignPaddingModeMax: 337 | { 338 | tailPadding = tailPadding == -1 ? -1 : tailPadding; 339 | paddings[tailIndex] = @( MAX( tailPadding , newTailPadding ) ); 340 | } 341 | break; 342 | default: 343 | paddings[tailIndex] = @( newTailPadding ); 344 | break; 345 | } 346 | 347 | ____STEP_OUT( tail ) 348 | 349 | // NSLog( @"%d| head:%d| match:%d| tail:%d", level, level+1, level+2, level+3 ); 350 | // NSLog( @"\n level:%d %@\n head:%@\n tail:%@\nmatch:%@", level, pattern, head, tail, match ); 351 | } 352 | 353 | - (NSArray *)componentsSeparatedByRegexPattern:(NSString *)pattern position:(XAlignPosition)position match:(NSString **)match 354 | { 355 | NSError * error = nil; 356 | NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error]; 357 | 358 | if ( error ) 359 | { 360 | NSLog( @"[NSString+XAlign](%s): pattern is illegal. error: %@", __PRETTY_FUNCTION__, error ); 361 | return nil; 362 | } 363 | 364 | NSArray * matches = [regex matchesInString:self options:NSMatchingReportProgress range:NSMakeRange(0, self.length)]; 365 | 366 | if ( 0 == matches.count ) 367 | return nil; 368 | 369 | NSTextCheckingResult * matchResult = nil; 370 | 371 | // for ( matchResult in matches ) 372 | // { 373 | // NSLog( @"|||%@|||", [self substringWithRange:NSMakeRange(0, NSMaxRange([matchResult range]))]); 374 | // } 375 | 376 | switch ( position ) 377 | { 378 | case XAlignPositionFisrt: 379 | matchResult = [matches firstObject]; 380 | break; 381 | case XAlignPositionLast: 382 | matchResult = [matches lastObject]; 383 | break; 384 | 385 | default: 386 | if ( position >= matches.count ) 387 | matchResult = nil; 388 | else 389 | matchResult = matches[position-1]; 390 | break; 391 | } 392 | 393 | if ( nil == match ) 394 | return nil; 395 | 396 | *match = [self substringWithRange:[matchResult range]]; 397 | 398 | NSRange headRange = NSMakeRange( 0, [matchResult range].location ); 399 | NSRange tailRange = NSMakeRange( NSMaxRange([matchResult range]), self.length - NSMaxRange([matchResult range]) ); 400 | 401 | NSString * head = [self substringWithRange:headRange] ?: @""; 402 | NSString * tail = [self substringWithRange:tailRange] ?: @""; 403 | 404 | return @[ head, tail ]; 405 | } 406 | 407 | @end 408 | -------------------------------------------------------------------------------- /Source/Patterns.bundle/default.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | id 7 | 0 8 | title 9 | By First = 10 | selector 11 | align: 12 | specifier 13 | = 14 | patterns 15 | 16 | 17 | string 18 | ^\s* 19 | tailMode 20 | 2 21 | matchMode 22 | 1 23 | control 24 | 25 | string 26 | 27 | needPadding 28 | 29 | paddingString 30 | 31 | 32 | 33 | 34 | string 35 | \s*(?<=[\w\s])[\|\+\-\*]?=(?=[\w\s])\s* 36 | position 37 | -1 38 | control 39 | 40 | needTrim 41 | 42 | format 43 | %@ 44 | needFormat 45 | 46 | 47 | 48 | 49 | string 50 | \s*//.*$ 51 | isOptional 52 | 53 | control 54 | 55 | format 56 | %@ 57 | needFormat 58 | 59 | needTrim 60 | 61 | 62 | 63 | 64 | string 65 | \s*/\*.*$ 66 | isOptional 67 | 68 | control 69 | 70 | format 71 | %@ 72 | needFormat 73 | 74 | needTrim 75 | 76 | 77 | 78 | 79 | 80 | 81 | id 82 | 1 83 | title 84 | Define Group 85 | selector 86 | align: 87 | specifier 88 | #define 89 | patterns 90 | 91 | 92 | string 93 | ^\s* 94 | tailMode 95 | 2 96 | control 97 | 98 | string 99 | 100 | 101 | 102 | 103 | string 104 | \s+ 105 | tailMode 106 | 2 107 | control 108 | 109 | string 110 | 111 | 112 | 113 | 114 | string 115 | \s*//.*$ 116 | isOptional 117 | 118 | control 119 | 120 | format 121 | %@ 122 | needFormat 123 | 124 | needTrim 125 | 126 | 127 | 128 | 129 | string 130 | \s*/\*.*$ 131 | isOptional 132 | 133 | control 134 | 135 | format 136 | %@ 137 | needFormat 138 | 139 | needTrim 140 | 141 | 142 | 143 | 144 | 145 | 146 | id 147 | 2 148 | title 149 | Property Group 150 | selector 151 | align: 152 | specifier 153 | @property 154 | patterns 155 | 156 | 157 | string 158 | ^\s*@property\s* 159 | tailMode 160 | 2 161 | control 162 | 163 | string 164 | @property 165 | 166 | 167 | 168 | string 169 | (?<=)\)\s* 170 | tailMode 171 | 2 172 | control 173 | 174 | string 175 | ) 176 | 177 | 178 | 179 | string 180 | \w+ 181 | matchMode 182 | 2 183 | control 184 | 185 | needPadding 186 | 187 | paddingString 188 | 189 | isMatchPadding 190 | 191 | 192 | 193 | 194 | string 195 | \s*\w+; 196 | isOptional 197 | 198 | control 199 | 200 | needFormat 201 | 202 | needTrim 203 | 204 | format 205 | %@ 206 | 207 | 208 | 209 | string 210 | \s*\*+\s*\w+; 211 | isOptional 212 | 213 | control 214 | 215 | format 216 | %@ 217 | needTrim 218 | 219 | needFormat 220 | 221 | 222 | 223 | 224 | string 225 | \s*//.*$ 226 | isOptional 227 | 228 | control 229 | 230 | format 231 | %@ 232 | needFormat 233 | 234 | needTrim 235 | 236 | 237 | 238 | 239 | string 240 | \s*/\*.*$ 241 | isOptional 242 | 243 | control 244 | 245 | format 246 | %@ 247 | needFormat 248 | 249 | needTrim 250 | 251 | 252 | 253 | 254 | 255 | 256 | id 257 | 3 258 | title 259 | Variables Group 260 | selector 261 | align: 262 | patterns 263 | 264 | 265 | string 266 | ^\s* 267 | tailMode 268 | 2 269 | matchMode 270 | 1 271 | control 272 | 273 | string 274 | 275 | needPadding 276 | 277 | paddingString 278 | 279 | 280 | 281 | 282 | string 283 | [\s\*]+ 284 | control 285 | 286 | foundString 287 | * 288 | needFormatWhenFound 289 | 290 | notFoundFormat 291 | %@ 292 | format 293 | %@ 294 | needTrim 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | -------------------------------------------------------------------------------- /Source/XAlignPattern.h: -------------------------------------------------------------------------------- 1 | // 2 | // XAlignPattern.h 3 | // main 4 | // 5 | // Created by QFish on 11/30/13. 6 | // Copyright (c) 2013 net.qfish. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum XAlignPosition{ 12 | XAlignPositionFisrt = -1, 13 | XAlignPositionLast, 14 | } XAlignPosition; 15 | 16 | typedef enum XAlignPaddingMode { 17 | XAlignPaddingModeNone = 0, 18 | XAlignPaddingModeMin, 19 | XAlignPaddingModeMax, 20 | } XAlignPaddingMode; 21 | 22 | typedef NSString * (^XAlignPatternControlBlockU)(NSUInteger padding); 23 | typedef NSString * (^XAlignPatternControlBlockUS)(NSUInteger padding, NSString * match); 24 | 25 | @interface XAlignPadding : NSObject 26 | + (NSString *)stringWithFormat:(NSString *)format; 27 | @end 28 | 29 | @interface XAlignPattern : NSObject 30 | @property (nonatomic, assign) BOOL isOptional; 31 | @property (nonatomic, retain) NSString * string; 32 | @property (nonatomic, assign) XAlignPosition position; 33 | @property (nonatomic, assign) XAlignPaddingMode headMode; 34 | @property (nonatomic, assign) XAlignPaddingMode matchMode; 35 | @property (nonatomic, assign) XAlignPaddingMode tailMode; 36 | @property (nonatomic, copy) XAlignPatternControlBlockUS control; 37 | + (NSArray *)patterns; 38 | @end 39 | 40 | @interface XAlignPatternManager : NSObject 41 | 42 | + (instancetype)sharedInstance; 43 | 44 | @property (nonatomic, strong) NSMutableDictionary * specifiers; 45 | 46 | + (void)launch; 47 | 48 | + (void)setupWithRawArray:(NSArray *)array; 49 | 50 | + (NSArray *)patternGroupsWithContentsOfFile:(NSString *)name; 51 | + (NSArray *)patternGroupsWithRawArray:(NSArray *)array; 52 | + (NSArray *)patternGroupMatchWithString:(NSString *)string; 53 | + (NSArray *)patternGroupWithDictinary:(NSDictionary *)dictionary; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Source/XAlignPattern.m: -------------------------------------------------------------------------------- 1 | // 2 | // XAlignPattern.m 3 | // main 4 | // 5 | // Created by QFish on 11/30/13. 6 | // Copyright (c) 2013 net.qfish. All rights reserved. 7 | // 8 | 9 | #define kPatterns @"patterns" 10 | #define kPatternID @"id" 11 | #define kPatternType @"type" 12 | #define kPatternPosition @"position" 13 | #define kPatternHeadMode @"headMode" 14 | #define kPatternTailMode @"tailMode" 15 | #define kPatternMatchMode @"matchMode" 16 | #define kPatternIsOptional @"isOptional" 17 | #define kPatternString @"string" 18 | #define kPatternControl @"control" 19 | #define kPatternControlString @"string" 20 | #define kPatternControlFoundString @"foundString" 21 | #define kPatternControlFormat @"format" 22 | #define kPatternControlNotFoundFormat @"notFoundFormat" 23 | #define kPatternControlNeedTrim @"needTrim" 24 | #define kPatternControlNeedFormat @"needFormat" 25 | #define kPatternControlNeedFormatWhenFound @"needFormatWhenFound" 26 | #define kPatternControlNeedPadding @"needPadding" 27 | #define kPatternControlPaddingString @"paddingString" 28 | #define kPatternControlIsMatchPadding @"isMatchPadding" 29 | 30 | #import "XAlignPattern.h" 31 | #import "NSString+XAlign.h" 32 | 33 | @implementation XAlignPadding 34 | 35 | + (NSString *)stringWithFormat:(NSString *)format 36 | { 37 | // {padding * @" "} 38 | // {match.trim} 39 | // {match} 40 | // @" %@", {match} 41 | // 42 | 43 | return nil; 44 | } 45 | 46 | @end 47 | 48 | #pragma mark - 49 | 50 | @implementation XAlignPattern 51 | 52 | + (NSArray *)patterns 53 | { 54 | static NSArray * __items = nil; 55 | 56 | if ( __items == nil ) 57 | { 58 | NSString * patternsBundlePath = [[NSBundle mainBundle] pathForResource:@"Patterns" ofType:@"bundle"]; 59 | NSString * filePath = [[NSBundle bundleWithPath:patternsBundlePath] pathForResource:@"default" ofType:@"plist"]; 60 | __items = [NSArray arrayWithContentsOfFile:filePath]; 61 | } 62 | 63 | return __items; 64 | } 65 | 66 | - (NSString *)description 67 | { 68 | return self.string; 69 | } 70 | 71 | @end 72 | 73 | @interface XAlignPatternManager() 74 | @property (nonatomic, strong) NSMutableDictionary * cache; 75 | @end 76 | 77 | @implementation XAlignPatternManager 78 | 79 | + (instancetype)sharedInstance 80 | { 81 | static XAlignPatternManager * i = nil; 82 | static dispatch_once_t onceToken; 83 | dispatch_once(&onceToken, ^{ 84 | i = [[[self class] alloc] init]; 85 | }); 86 | return i; 87 | } 88 | 89 | - (id)init 90 | { 91 | self = [super init]; 92 | if (self) { 93 | self.cache = [NSMutableDictionary dictionary]; 94 | self.specifiers = [NSMutableDictionary dictionary]; 95 | } 96 | return self; 97 | } 98 | 99 | #pragma mark - setup 100 | 101 | + (void)launch 102 | { 103 | [self setupWithRawArray:[XAlignPattern patterns]]; 104 | } 105 | 106 | + (void)setupWithRawArray:(NSArray *)array 107 | { 108 | [self setupSpecifiersWithRawArray:array]; 109 | } 110 | 111 | #pragma mark - spectifier 112 | 113 | + (NSArray *)setupSpecifiersWithRawArray:(NSArray *)array 114 | { 115 | if ( !array ) 116 | return nil; 117 | 118 | for ( NSDictionary * item in array ) 119 | { 120 | NSString * spec = item[@"specifier"]; 121 | 122 | if ( spec ) 123 | { 124 | [XAlignPatternManager sharedInstance].specifiers[spec] = item; 125 | } 126 | } 127 | 128 | return nil; 129 | } 130 | 131 | + (NSDictionary *)rawPatternWithString:(NSString *)string 132 | { 133 | NSDictionary * specifiers = [XAlignPatternManager sharedInstance].specifiers; 134 | 135 | for ( NSString * spec in specifiers.allKeys ) 136 | { 137 | if ( NSNotFound != [string rangeOfString:spec].location ) 138 | { 139 | return specifiers[spec]; 140 | } 141 | } 142 | 143 | return nil; 144 | } 145 | 146 | + (NSArray *)patternGroupMatchWithString:(NSString *)string 147 | { 148 | NSDictionary * dict = [self rawPatternWithString:string]; 149 | return [self patternGroupWithDictinary:dict]; 150 | } 151 | 152 | #pragma mark - patternGroup 153 | 154 | + (NSArray *)patternGroupsWithContentsOfFile:(NSString *)name 155 | { 156 | NSString * filePath = [[NSBundle mainBundle] pathForResource:name ofType:@"plist"]; 157 | NSArray * rawArray = [[NSArray alloc]initWithContentsOfFile:filePath]; 158 | return [self patternGroupsWithRawArray:rawArray]; 159 | } 160 | 161 | + (NSArray *)patternGroupsWithRawArray:(NSArray *)rawArray 162 | { 163 | if ( !rawArray ) 164 | return nil; 165 | 166 | NSMutableArray * patternGroups = [NSMutableArray array]; 167 | 168 | for ( NSDictionary * dict in rawArray ) 169 | { 170 | NSArray * patternGroup = [self patternGroupWithDictinary:dict]; 171 | 172 | if ( patternGroup ) 173 | { 174 | [patternGroups addObject:patternGroup]; 175 | } 176 | } 177 | 178 | return patternGroups; 179 | } 180 | 181 | + (NSArray *)patternGroupWithDictinary:(NSDictionary *)dictionary 182 | { 183 | NSNumber * key = dictionary[kPatternID]; 184 | 185 | if ( !key ) 186 | return nil; 187 | 188 | NSMutableArray * patternGroup = [XAlignPatternManager sharedInstance].cache[key]; 189 | 190 | if ( nil == patternGroup ) 191 | { 192 | patternGroup = [NSMutableArray array]; 193 | 194 | for ( NSDictionary * pattern in dictionary[kPatterns] ) 195 | { 196 | NSString * string = pattern[kPatternString]; 197 | 198 | BOOL isOptional = [pattern[kPatternIsOptional] intValue]; 199 | XAlignPosition position = [pattern[kPatternPosition] intValue]; 200 | XAlignPaddingMode headMode = [pattern[kPatternHeadMode] intValue]; 201 | XAlignPaddingMode matchMode = [pattern[kPatternMatchMode] intValue]; 202 | XAlignPaddingMode tailMode = [pattern[kPatternTailMode] intValue]; 203 | 204 | NSDictionary * control = pattern[kPatternControl]; 205 | BOOL needTrim = [control[kPatternControlNeedTrim] boolValue]; 206 | BOOL needFormat = [control[kPatternControlNeedFormat] boolValue]; 207 | BOOL needFormatWhenFound = [control[kPatternControlNeedFormatWhenFound] boolValue]; 208 | BOOL needPadding = [control[kPatternControlNeedPadding] boolValue]; 209 | BOOL isMatchPadding = [control[kPatternControlIsMatchPadding] boolValue]; 210 | NSString * controlString = control[kPatternControlString]; 211 | NSString * paddingString = control[kPatternControlPaddingString]; 212 | NSString * foundString = control[kPatternControlFoundString]; 213 | NSString * format = control[kPatternControlFormat]; 214 | NSString * notFoundFormat = control[kPatternControlNotFoundFormat]; 215 | 216 | XAlignPattern * p = [[XAlignPattern alloc] init]; 217 | 218 | p.string = string; 219 | p.headMode = headMode; 220 | p.tailMode = tailMode; 221 | p.matchMode = matchMode; 222 | p.position = position; 223 | p.isOptional = isOptional; 224 | p.control = ^ NSString * ( NSUInteger padding, NSString * match ) 225 | { 226 | if ( needFormat || needPadding || needFormatWhenFound ) 227 | { 228 | NSString * result = match; 229 | 230 | if ( needTrim ) 231 | result = result.xtrim; 232 | 233 | if ( needFormatWhenFound ) 234 | { 235 | if ( NSNotFound == [match rangeOfString:foundString].location ) 236 | { 237 | if ( notFoundFormat ) 238 | result = [NSString stringWithFormat:notFoundFormat, result]; 239 | } 240 | else 241 | { 242 | if ( format ) 243 | result = [NSString stringWithFormat:format, result]; 244 | } 245 | } 246 | else if ( needFormat ) 247 | { 248 | result = [NSString stringWithFormat:format, result]; 249 | } 250 | 251 | if ( needPadding ) 252 | { 253 | if ( isMatchPadding ) { 254 | result = [result stringByPaddingToLength:padding withString:paddingString startingAtIndex:0]; 255 | } else { 256 | result = [controlString stringByPaddingToLength:padding withString:paddingString startingAtIndex:0]; 257 | } 258 | } 259 | 260 | return result; 261 | } 262 | 263 | return controlString; 264 | }; 265 | 266 | [patternGroup addObject:p]; 267 | } 268 | 269 | [XAlignPatternManager sharedInstance].cache[key] = patternGroup; 270 | } 271 | 272 | return patternGroup; 273 | } 274 | 275 | @end 276 | -------------------------------------------------------------------------------- /SourceEditorExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | XAlign 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | XAlign 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 201611092325 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 | Auto Align 38 | 39 | 40 | XCSourceEditorExtensionPrincipalClass 41 | SourceEditorExtension 42 | 43 | NSExtensionPointIdentifier 44 | com.apple.dt.Xcode.extension.source-editor 45 | 46 | NSHumanReadableCopyright 47 | Copyright © 2016 QFish. All rights reserved. 48 | 49 | 50 | -------------------------------------------------------------------------------- /SourceEditorExtension/SourceEditorCommand.h: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorCommand.h 3 | // SourceEditorExtension 4 | // 5 | // Created by QFish on 03/11/2016. 6 | // Copyright © 2016 QFish. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SourceEditorCommand : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SourceEditorExtension/SourceEditorCommand.m: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorCommand.m 3 | // SourceEditorExtension 4 | // 5 | // Created by QFish on 03/11/2016. 6 | // Copyright © 2016 QFish. All rights reserved. 7 | // 8 | 9 | #import "SourceEditorCommand.h" 10 | #import "XAlignPattern.h" 11 | #import "NSString+XAlign.h" 12 | 13 | @implementation SourceEditorCommand 14 | 15 | - (void)performCommandWithInvocation:(XCSourceEditorCommandInvocation *)invocation completionHandler:(void (^)(NSError * _Nullable nilOrError))completionHandler 16 | { 17 | // Implement your command here, invoking the completion handler when done. Pass it nil on success, and an NSError on failure. 18 | 19 | if ([invocation.commandIdentifier hasSuffix:@"SourceEditorCommand"]) 20 | { 21 | [[self class] autoAlign:invocation]; 22 | } 23 | 24 | completionHandler(nil); 25 | } 26 | 27 | + (void)autoAlign:(XCSourceEditorCommandInvocation *)invocation 28 | { 29 | NSMutableArray * selections = [NSMutableArray array]; 30 | 31 | for ( XCSourceTextRange *range in invocation.buffer.selections ) 32 | { 33 | for ( NSInteger i = range.start.line; i < range.end.line ; i++) 34 | { 35 | [selections addObject:invocation.buffer.lines[i]]; 36 | } 37 | } 38 | 39 | NSString * selectedString = [selections componentsJoinedByString:@""]; 40 | 41 | NSArray * patternGroup = [XAlignPatternManager patternGroupMatchWithString:selectedString]; 42 | 43 | if ( !patternGroup ) 44 | return; 45 | 46 | NSString * alignedString = [selectedString stringByAligningWithPatterns:patternGroup]; 47 | 48 | NSArray * result = [alignedString componentsSeparatedByString:@"\n"]; 49 | 50 | for ( XCSourceTextRange *range in invocation.buffer.selections ) 51 | { 52 | for ( NSInteger i = range.start.line, j=0; i < range.end.line ; i++, j++ ) 53 | { 54 | invocation.buffer.lines[i] = result[j]; 55 | } 56 | } 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /SourceEditorExtension/SourceEditorExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SourceEditorExtension/SourceEditorExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorExtension.h 3 | // SourceEditorExtension 4 | // 5 | // Created by QFish on 03/11/2016. 6 | // Copyright © 2016 QFish. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SourceEditorExtension : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SourceEditorExtension/SourceEditorExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorExtension.m 3 | // SourceEditorExtension 4 | // 5 | // Created by QFish on 03/11/2016. 6 | // Copyright © 2016 QFish. All rights reserved. 7 | // 8 | 9 | #import "SourceEditorExtension.h" 10 | #import "XAlignPattern.h" 11 | 12 | @implementation SourceEditorExtension 13 | 14 | - (void)extensionDidFinishLaunching 15 | { 16 | // If your extension needs to do any work at launch, implement this optional method. 17 | [XAlignPatternManager launch]; 18 | } 19 | 20 | //- (NSArray *> *)commandDefinitions 21 | //{ 22 | // // If your extension needs to return a collection of command definitions that differs from those in its Info.plist, implement this optional property getter. 23 | // return @[]; 24 | //} 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /XAlign.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3C1514C026F37BB400206BC4 /* XcodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1514BF26F37BB400206BC4 /* XcodeKit.framework */; }; 11 | 3C1514C126F37BB400206BC4 /* XcodeKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1514BF26F37BB400206BC4 /* XcodeKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 12 | E93E2A7C1DCB8ED900F7BEA4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E93E2A7B1DCB8ED900F7BEA4 /* AppDelegate.m */; }; 13 | E93E2A7F1DCB8ED900F7BEA4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E93E2A7E1DCB8ED900F7BEA4 /* main.m */; }; 14 | E93E2A821DCB8ED900F7BEA4 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E93E2A811DCB8ED900F7BEA4 /* ViewController.m */; }; 15 | E93E2A841DCB8ED900F7BEA4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E93E2A831DCB8ED900F7BEA4 /* Assets.xcassets */; }; 16 | E93E2A871DCB8ED900F7BEA4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E93E2A851DCB8ED900F7BEA4 /* Main.storyboard */; }; 17 | E93E2AAC1DCB8F6400F7BEA4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E93E2A941DCB8EEF00F7BEA4 /* Cocoa.framework */; }; 18 | E93E2AB21DCB8F6400F7BEA4 /* SourceEditorExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = E93E2AB11DCB8F6400F7BEA4 /* SourceEditorExtension.m */; }; 19 | E93E2AB51DCB8F6400F7BEA4 /* SourceEditorCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = E93E2AB41DCB8F6400F7BEA4 /* SourceEditorCommand.m */; }; 20 | E93E2AB91DCB8F6400F7BEA4 /* SourceEditorExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = E93E2AAB1DCB8F6400F7BEA4 /* SourceEditorExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 21 | E93E2AC21DCB914400F7BEA4 /* NSString+XAlign.m in Sources */ = {isa = PBXBuildFile; fileRef = E93E2ABF1DCB914400F7BEA4 /* NSString+XAlign.m */; }; 22 | E93E2AC31DCB914400F7BEA4 /* XAlignPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = E93E2AC11DCB914400F7BEA4 /* XAlignPattern.m */; }; 23 | E93E2AC51DCB93FA00F7BEA4 /* Patterns.bundle in Resources */ = {isa = PBXBuildFile; fileRef = E93E2AC41DCB93FA00F7BEA4 /* Patterns.bundle */; }; 24 | E98288BB1DD61C8000F24778 /* Patterns.bundle in Resources */ = {isa = PBXBuildFile; fileRef = E93E2AC41DCB93FA00F7BEA4 /* Patterns.bundle */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | E93E2AB71DCB8F6400F7BEA4 /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = E93E2A6F1DCB8ED900F7BEA4 /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = E93E2AAA1DCB8F6400F7BEA4; 33 | remoteInfo = SourceEditorExtension; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXCopyFilesBuildPhase section */ 38 | 3C1514C226F37BB400206BC4 /* Embed Frameworks */ = { 39 | isa = PBXCopyFilesBuildPhase; 40 | buildActionMask = 2147483647; 41 | dstPath = ""; 42 | dstSubfolderSpec = 10; 43 | files = ( 44 | 3C1514C126F37BB400206BC4 /* XcodeKit.framework in Embed Frameworks */, 45 | ); 46 | name = "Embed Frameworks"; 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | E93E2AA61DCB8EEF00F7BEA4 /* Embed App Extensions */ = { 50 | isa = PBXCopyFilesBuildPhase; 51 | buildActionMask = 2147483647; 52 | dstPath = ""; 53 | dstSubfolderSpec = 13; 54 | files = ( 55 | E93E2AB91DCB8F6400F7BEA4 /* SourceEditorExtension.appex in Embed App Extensions */, 56 | ); 57 | name = "Embed App Extensions"; 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXCopyFilesBuildPhase section */ 61 | 62 | /* Begin PBXFileReference section */ 63 | 3C1514BF26F37BB400206BC4 /* XcodeKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XcodeKit.framework; path = Library/Frameworks/XcodeKit.framework; sourceTree = DEVELOPER_DIR; }; 64 | E93E2A771DCB8ED900F7BEA4 /* XAlign.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XAlign.app; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | E93E2A7A1DCB8ED900F7BEA4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 66 | E93E2A7B1DCB8ED900F7BEA4 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 67 | E93E2A7E1DCB8ED900F7BEA4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 68 | E93E2A801DCB8ED900F7BEA4 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 69 | E93E2A811DCB8ED900F7BEA4 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 70 | E93E2A831DCB8ED900F7BEA4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 71 | E93E2A861DCB8ED900F7BEA4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 72 | E93E2A881DCB8ED900F7BEA4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 73 | E93E2A941DCB8EEF00F7BEA4 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 74 | E93E2AAB1DCB8F6400F7BEA4 /* SourceEditorExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SourceEditorExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | E93E2AAF1DCB8F6400F7BEA4 /* SourceEditorExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SourceEditorExtension.entitlements; sourceTree = ""; }; 76 | E93E2AB01DCB8F6400F7BEA4 /* SourceEditorExtension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SourceEditorExtension.h; sourceTree = ""; }; 77 | E93E2AB11DCB8F6400F7BEA4 /* SourceEditorExtension.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SourceEditorExtension.m; sourceTree = ""; }; 78 | E93E2AB31DCB8F6400F7BEA4 /* SourceEditorCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SourceEditorCommand.h; sourceTree = ""; }; 79 | E93E2AB41DCB8F6400F7BEA4 /* SourceEditorCommand.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SourceEditorCommand.m; sourceTree = ""; }; 80 | E93E2AB61DCB8F6400F7BEA4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 81 | E93E2ABE1DCB914400F7BEA4 /* NSString+XAlign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+XAlign.h"; sourceTree = ""; }; 82 | E93E2ABF1DCB914400F7BEA4 /* NSString+XAlign.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+XAlign.m"; sourceTree = ""; }; 83 | E93E2AC01DCB914400F7BEA4 /* XAlignPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XAlignPattern.h; sourceTree = ""; }; 84 | E93E2AC11DCB914400F7BEA4 /* XAlignPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XAlignPattern.m; sourceTree = ""; }; 85 | E93E2AC41DCB93FA00F7BEA4 /* Patterns.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Patterns.bundle; sourceTree = ""; }; 86 | /* End PBXFileReference section */ 87 | 88 | /* Begin PBXFrameworksBuildPhase section */ 89 | E93E2A741DCB8ED900F7BEA4 /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | ); 94 | runOnlyForDeploymentPostprocessing = 0; 95 | }; 96 | E93E2AA81DCB8F6400F7BEA4 /* Frameworks */ = { 97 | isa = PBXFrameworksBuildPhase; 98 | buildActionMask = 2147483647; 99 | files = ( 100 | E93E2AAC1DCB8F6400F7BEA4 /* Cocoa.framework in Frameworks */, 101 | 3C1514C026F37BB400206BC4 /* XcodeKit.framework in Frameworks */, 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | /* End PBXFrameworksBuildPhase section */ 106 | 107 | /* Begin PBXGroup section */ 108 | E93E2A6E1DCB8ED900F7BEA4 = { 109 | isa = PBXGroup; 110 | children = ( 111 | E93E2A791DCB8ED900F7BEA4 /* XAlign */, 112 | E93E2ABD1DCB914400F7BEA4 /* Source */, 113 | E93E2AAD1DCB8F6400F7BEA4 /* SourceEditorExtension */, 114 | E93E2A931DCB8EEF00F7BEA4 /* Frameworks */, 115 | E93E2A781DCB8ED900F7BEA4 /* Products */, 116 | ); 117 | sourceTree = ""; 118 | }; 119 | E93E2A781DCB8ED900F7BEA4 /* Products */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | E93E2A771DCB8ED900F7BEA4 /* XAlign.app */, 123 | E93E2AAB1DCB8F6400F7BEA4 /* SourceEditorExtension.appex */, 124 | ); 125 | name = Products; 126 | sourceTree = ""; 127 | }; 128 | E93E2A791DCB8ED900F7BEA4 /* XAlign */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | E93E2A7A1DCB8ED900F7BEA4 /* AppDelegate.h */, 132 | E93E2A7B1DCB8ED900F7BEA4 /* AppDelegate.m */, 133 | E93E2A801DCB8ED900F7BEA4 /* ViewController.h */, 134 | E93E2A811DCB8ED900F7BEA4 /* ViewController.m */, 135 | E93E2A831DCB8ED900F7BEA4 /* Assets.xcassets */, 136 | E93E2A851DCB8ED900F7BEA4 /* Main.storyboard */, 137 | E93E2A881DCB8ED900F7BEA4 /* Info.plist */, 138 | E93E2A7D1DCB8ED900F7BEA4 /* Supporting Files */, 139 | ); 140 | path = XAlign; 141 | sourceTree = ""; 142 | }; 143 | E93E2A7D1DCB8ED900F7BEA4 /* Supporting Files */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | E93E2A7E1DCB8ED900F7BEA4 /* main.m */, 147 | ); 148 | name = "Supporting Files"; 149 | sourceTree = ""; 150 | }; 151 | E93E2A931DCB8EEF00F7BEA4 /* Frameworks */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 3C1514BF26F37BB400206BC4 /* XcodeKit.framework */, 155 | E93E2A941DCB8EEF00F7BEA4 /* Cocoa.framework */, 156 | ); 157 | name = Frameworks; 158 | sourceTree = ""; 159 | }; 160 | E93E2AAD1DCB8F6400F7BEA4 /* SourceEditorExtension */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | E93E2AB01DCB8F6400F7BEA4 /* SourceEditorExtension.h */, 164 | E93E2AB11DCB8F6400F7BEA4 /* SourceEditorExtension.m */, 165 | E93E2AB31DCB8F6400F7BEA4 /* SourceEditorCommand.h */, 166 | E93E2AB41DCB8F6400F7BEA4 /* SourceEditorCommand.m */, 167 | E93E2AB61DCB8F6400F7BEA4 /* Info.plist */, 168 | E93E2AAE1DCB8F6400F7BEA4 /* Supporting Files */, 169 | ); 170 | path = SourceEditorExtension; 171 | sourceTree = ""; 172 | }; 173 | E93E2AAE1DCB8F6400F7BEA4 /* Supporting Files */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | E93E2AAF1DCB8F6400F7BEA4 /* SourceEditorExtension.entitlements */, 177 | ); 178 | name = "Supporting Files"; 179 | sourceTree = ""; 180 | }; 181 | E93E2ABD1DCB914400F7BEA4 /* Source */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | E93E2AC41DCB93FA00F7BEA4 /* Patterns.bundle */, 185 | E93E2ABE1DCB914400F7BEA4 /* NSString+XAlign.h */, 186 | E93E2ABF1DCB914400F7BEA4 /* NSString+XAlign.m */, 187 | E93E2AC01DCB914400F7BEA4 /* XAlignPattern.h */, 188 | E93E2AC11DCB914400F7BEA4 /* XAlignPattern.m */, 189 | ); 190 | path = Source; 191 | sourceTree = ""; 192 | }; 193 | /* End PBXGroup section */ 194 | 195 | /* Begin PBXNativeTarget section */ 196 | E93E2A761DCB8ED900F7BEA4 /* XAlign */ = { 197 | isa = PBXNativeTarget; 198 | buildConfigurationList = E93E2A8B1DCB8ED900F7BEA4 /* Build configuration list for PBXNativeTarget "XAlign" */; 199 | buildPhases = ( 200 | E93E2A731DCB8ED900F7BEA4 /* Sources */, 201 | E93E2A741DCB8ED900F7BEA4 /* Frameworks */, 202 | E93E2A751DCB8ED900F7BEA4 /* Resources */, 203 | E93E2AA61DCB8EEF00F7BEA4 /* Embed App Extensions */, 204 | ); 205 | buildRules = ( 206 | ); 207 | dependencies = ( 208 | E93E2AB81DCB8F6400F7BEA4 /* PBXTargetDependency */, 209 | ); 210 | name = XAlign; 211 | productName = XAlign; 212 | productReference = E93E2A771DCB8ED900F7BEA4 /* XAlign.app */; 213 | productType = "com.apple.product-type.application"; 214 | }; 215 | E93E2AAA1DCB8F6400F7BEA4 /* SourceEditorExtension */ = { 216 | isa = PBXNativeTarget; 217 | buildConfigurationList = E93E2ABA1DCB8F6400F7BEA4 /* Build configuration list for PBXNativeTarget "SourceEditorExtension" */; 218 | buildPhases = ( 219 | E93E2AA71DCB8F6400F7BEA4 /* Sources */, 220 | E93E2AA81DCB8F6400F7BEA4 /* Frameworks */, 221 | E93E2AA91DCB8F6400F7BEA4 /* Resources */, 222 | 3C1514C226F37BB400206BC4 /* Embed Frameworks */, 223 | ); 224 | buildRules = ( 225 | ); 226 | dependencies = ( 227 | ); 228 | name = SourceEditorExtension; 229 | productName = SourceEditorExtension; 230 | productReference = E93E2AAB1DCB8F6400F7BEA4 /* SourceEditorExtension.appex */; 231 | productType = "com.apple.product-type.xcode-extension"; 232 | }; 233 | /* End PBXNativeTarget section */ 234 | 235 | /* Begin PBXProject section */ 236 | E93E2A6F1DCB8ED900F7BEA4 /* Project object */ = { 237 | isa = PBXProject; 238 | attributes = { 239 | LastUpgradeCheck = 1200; 240 | ORGANIZATIONNAME = QFish; 241 | TargetAttributes = { 242 | E93E2A761DCB8ED900F7BEA4 = { 243 | CreatedOnToolsVersion = 8.1; 244 | DevelopmentTeam = W22HJ57AL8; 245 | ProvisioningStyle = Automatic; 246 | }; 247 | E93E2AAA1DCB8F6400F7BEA4 = { 248 | CreatedOnToolsVersion = 8.1; 249 | DevelopmentTeam = W22HJ57AL8; 250 | ProvisioningStyle = Automatic; 251 | }; 252 | }; 253 | }; 254 | buildConfigurationList = E93E2A721DCB8ED900F7BEA4 /* Build configuration list for PBXProject "XAlign" */; 255 | compatibilityVersion = "Xcode 3.2"; 256 | developmentRegion = en; 257 | hasScannedForEncodings = 0; 258 | knownRegions = ( 259 | en, 260 | Base, 261 | ); 262 | mainGroup = E93E2A6E1DCB8ED900F7BEA4; 263 | productRefGroup = E93E2A781DCB8ED900F7BEA4 /* Products */; 264 | projectDirPath = ""; 265 | projectRoot = ""; 266 | targets = ( 267 | E93E2A761DCB8ED900F7BEA4 /* XAlign */, 268 | E93E2AAA1DCB8F6400F7BEA4 /* SourceEditorExtension */, 269 | ); 270 | }; 271 | /* End PBXProject section */ 272 | 273 | /* Begin PBXResourcesBuildPhase section */ 274 | E93E2A751DCB8ED900F7BEA4 /* Resources */ = { 275 | isa = PBXResourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | E93E2A841DCB8ED900F7BEA4 /* Assets.xcassets in Resources */, 279 | E93E2A871DCB8ED900F7BEA4 /* Main.storyboard in Resources */, 280 | E93E2AC51DCB93FA00F7BEA4 /* Patterns.bundle in Resources */, 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | }; 284 | E93E2AA91DCB8F6400F7BEA4 /* Resources */ = { 285 | isa = PBXResourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | E98288BB1DD61C8000F24778 /* Patterns.bundle in Resources */, 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | }; 292 | /* End PBXResourcesBuildPhase section */ 293 | 294 | /* Begin PBXSourcesBuildPhase section */ 295 | E93E2A731DCB8ED900F7BEA4 /* Sources */ = { 296 | isa = PBXSourcesBuildPhase; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | E93E2A821DCB8ED900F7BEA4 /* ViewController.m in Sources */, 300 | E93E2A7F1DCB8ED900F7BEA4 /* main.m in Sources */, 301 | E93E2A7C1DCB8ED900F7BEA4 /* AppDelegate.m in Sources */, 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | E93E2AA71DCB8F6400F7BEA4 /* Sources */ = { 306 | isa = PBXSourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | E93E2AB21DCB8F6400F7BEA4 /* SourceEditorExtension.m in Sources */, 310 | E93E2AB51DCB8F6400F7BEA4 /* SourceEditorCommand.m in Sources */, 311 | E93E2AC21DCB914400F7BEA4 /* NSString+XAlign.m in Sources */, 312 | E93E2AC31DCB914400F7BEA4 /* XAlignPattern.m in Sources */, 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | /* End PBXSourcesBuildPhase section */ 317 | 318 | /* Begin PBXTargetDependency section */ 319 | E93E2AB81DCB8F6400F7BEA4 /* PBXTargetDependency */ = { 320 | isa = PBXTargetDependency; 321 | target = E93E2AAA1DCB8F6400F7BEA4 /* SourceEditorExtension */; 322 | targetProxy = E93E2AB71DCB8F6400F7BEA4 /* PBXContainerItemProxy */; 323 | }; 324 | /* End PBXTargetDependency section */ 325 | 326 | /* Begin PBXVariantGroup section */ 327 | E93E2A851DCB8ED900F7BEA4 /* Main.storyboard */ = { 328 | isa = PBXVariantGroup; 329 | children = ( 330 | E93E2A861DCB8ED900F7BEA4 /* Base */, 331 | ); 332 | name = Main.storyboard; 333 | sourceTree = ""; 334 | }; 335 | /* End PBXVariantGroup section */ 336 | 337 | /* Begin XCBuildConfiguration section */ 338 | E93E2A891DCB8ED900F7BEA4 /* Debug */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ALWAYS_SEARCH_USER_PATHS = NO; 342 | CLANG_ANALYZER_NONNULL = YES; 343 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 344 | CLANG_CXX_LIBRARY = "libc++"; 345 | CLANG_ENABLE_MODULES = YES; 346 | CLANG_ENABLE_OBJC_ARC = YES; 347 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 348 | CLANG_WARN_BOOL_CONVERSION = YES; 349 | CLANG_WARN_COMMA = YES; 350 | CLANG_WARN_CONSTANT_CONVERSION = YES; 351 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 352 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 353 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 354 | CLANG_WARN_EMPTY_BODY = YES; 355 | CLANG_WARN_ENUM_CONVERSION = YES; 356 | CLANG_WARN_INFINITE_RECURSION = YES; 357 | CLANG_WARN_INT_CONVERSION = YES; 358 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 359 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 360 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 361 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 362 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 363 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 364 | CLANG_WARN_STRICT_PROTOTYPES = YES; 365 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 366 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 367 | CLANG_WARN_UNREACHABLE_CODE = YES; 368 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 369 | CODE_SIGN_IDENTITY = "-"; 370 | COPY_PHASE_STRIP = NO; 371 | DEBUG_INFORMATION_FORMAT = dwarf; 372 | ENABLE_STRICT_OBJC_MSGSEND = YES; 373 | ENABLE_TESTABILITY = YES; 374 | GCC_C_LANGUAGE_STANDARD = gnu99; 375 | GCC_DYNAMIC_NO_PIC = NO; 376 | GCC_NO_COMMON_BLOCKS = YES; 377 | GCC_OPTIMIZATION_LEVEL = 0; 378 | GCC_PREPROCESSOR_DEFINITIONS = ( 379 | "DEBUG=1", 380 | "$(inherited)", 381 | ); 382 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 383 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 384 | GCC_WARN_UNDECLARED_SELECTOR = YES; 385 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 386 | GCC_WARN_UNUSED_FUNCTION = YES; 387 | GCC_WARN_UNUSED_VARIABLE = YES; 388 | MACOSX_DEPLOYMENT_TARGET = 10.10; 389 | MTL_ENABLE_DEBUG_INFO = YES; 390 | ONLY_ACTIVE_ARCH = YES; 391 | SDKROOT = macosx; 392 | }; 393 | name = Debug; 394 | }; 395 | E93E2A8A1DCB8ED900F7BEA4 /* Release */ = { 396 | isa = XCBuildConfiguration; 397 | buildSettings = { 398 | ALWAYS_SEARCH_USER_PATHS = NO; 399 | CLANG_ANALYZER_NONNULL = YES; 400 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 401 | CLANG_CXX_LIBRARY = "libc++"; 402 | CLANG_ENABLE_MODULES = YES; 403 | CLANG_ENABLE_OBJC_ARC = YES; 404 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 405 | CLANG_WARN_BOOL_CONVERSION = YES; 406 | CLANG_WARN_COMMA = YES; 407 | CLANG_WARN_CONSTANT_CONVERSION = YES; 408 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 409 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 410 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 411 | CLANG_WARN_EMPTY_BODY = YES; 412 | CLANG_WARN_ENUM_CONVERSION = YES; 413 | CLANG_WARN_INFINITE_RECURSION = YES; 414 | CLANG_WARN_INT_CONVERSION = YES; 415 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 416 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 417 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 418 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 419 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 420 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 421 | CLANG_WARN_STRICT_PROTOTYPES = YES; 422 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 423 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 424 | CLANG_WARN_UNREACHABLE_CODE = YES; 425 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 426 | CODE_SIGN_IDENTITY = "-"; 427 | COPY_PHASE_STRIP = NO; 428 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 429 | ENABLE_NS_ASSERTIONS = NO; 430 | ENABLE_STRICT_OBJC_MSGSEND = YES; 431 | GCC_C_LANGUAGE_STANDARD = gnu99; 432 | GCC_NO_COMMON_BLOCKS = YES; 433 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 434 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 435 | GCC_WARN_UNDECLARED_SELECTOR = YES; 436 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 437 | GCC_WARN_UNUSED_FUNCTION = YES; 438 | GCC_WARN_UNUSED_VARIABLE = YES; 439 | MACOSX_DEPLOYMENT_TARGET = 10.10; 440 | MTL_ENABLE_DEBUG_INFO = NO; 441 | SDKROOT = macosx; 442 | }; 443 | name = Release; 444 | }; 445 | E93E2A8C1DCB8ED900F7BEA4 /* Debug */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 449 | CODE_SIGN_IDENTITY = "Mac Developer"; 450 | COMBINE_HIDPI_IMAGES = YES; 451 | DEVELOPMENT_TEAM = W22HJ57AL8; 452 | ENABLE_HARDENED_RUNTIME = YES; 453 | INFOPLIST_FILE = XAlign/Info.plist; 454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 455 | PRODUCT_BUNDLE_IDENTIFIER = qfi.sh.osx.xalign; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | }; 458 | name = Debug; 459 | }; 460 | E93E2A8D1DCB8ED900F7BEA4 /* Release */ = { 461 | isa = XCBuildConfiguration; 462 | buildSettings = { 463 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 464 | CODE_SIGN_IDENTITY = "Mac Developer"; 465 | COMBINE_HIDPI_IMAGES = YES; 466 | DEVELOPMENT_TEAM = W22HJ57AL8; 467 | ENABLE_HARDENED_RUNTIME = YES; 468 | INFOPLIST_FILE = XAlign/Info.plist; 469 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 470 | PRODUCT_BUNDLE_IDENTIFIER = qfi.sh.osx.xalign; 471 | PRODUCT_NAME = "$(TARGET_NAME)"; 472 | }; 473 | name = Release; 474 | }; 475 | E93E2ABB1DCB8F6400F7BEA4 /* Debug */ = { 476 | isa = XCBuildConfiguration; 477 | buildSettings = { 478 | CODE_SIGN_ENTITLEMENTS = SourceEditorExtension/SourceEditorExtension.entitlements; 479 | CODE_SIGN_IDENTITY = "Mac Developer"; 480 | COMBINE_HIDPI_IMAGES = YES; 481 | DEVELOPMENT_TEAM = W22HJ57AL8; 482 | ENABLE_HARDENED_RUNTIME = YES; 483 | INFOPLIST_FILE = SourceEditorExtension/Info.plist; 484 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; 485 | MACOSX_DEPLOYMENT_TARGET = 10.11; 486 | PRODUCT_BUNDLE_IDENTIFIER = qfi.sh.osx.xalign; 487 | PRODUCT_NAME = "$(TARGET_NAME)"; 488 | SKIP_INSTALL = YES; 489 | }; 490 | name = Debug; 491 | }; 492 | E93E2ABC1DCB8F6400F7BEA4 /* Release */ = { 493 | isa = XCBuildConfiguration; 494 | buildSettings = { 495 | CODE_SIGN_ENTITLEMENTS = SourceEditorExtension/SourceEditorExtension.entitlements; 496 | CODE_SIGN_IDENTITY = "Mac Developer"; 497 | COMBINE_HIDPI_IMAGES = YES; 498 | DEVELOPMENT_TEAM = W22HJ57AL8; 499 | ENABLE_HARDENED_RUNTIME = YES; 500 | INFOPLIST_FILE = SourceEditorExtension/Info.plist; 501 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; 502 | MACOSX_DEPLOYMENT_TARGET = 10.11; 503 | PRODUCT_BUNDLE_IDENTIFIER = qfi.sh.osx.xalign; 504 | PRODUCT_NAME = "$(TARGET_NAME)"; 505 | SKIP_INSTALL = YES; 506 | }; 507 | name = Release; 508 | }; 509 | /* End XCBuildConfiguration section */ 510 | 511 | /* Begin XCConfigurationList section */ 512 | E93E2A721DCB8ED900F7BEA4 /* Build configuration list for PBXProject "XAlign" */ = { 513 | isa = XCConfigurationList; 514 | buildConfigurations = ( 515 | E93E2A891DCB8ED900F7BEA4 /* Debug */, 516 | E93E2A8A1DCB8ED900F7BEA4 /* Release */, 517 | ); 518 | defaultConfigurationIsVisible = 0; 519 | defaultConfigurationName = Release; 520 | }; 521 | E93E2A8B1DCB8ED900F7BEA4 /* Build configuration list for PBXNativeTarget "XAlign" */ = { 522 | isa = XCConfigurationList; 523 | buildConfigurations = ( 524 | E93E2A8C1DCB8ED900F7BEA4 /* Debug */, 525 | E93E2A8D1DCB8ED900F7BEA4 /* Release */, 526 | ); 527 | defaultConfigurationIsVisible = 0; 528 | defaultConfigurationName = Release; 529 | }; 530 | E93E2ABA1DCB8F6400F7BEA4 /* Build configuration list for PBXNativeTarget "SourceEditorExtension" */ = { 531 | isa = XCConfigurationList; 532 | buildConfigurations = ( 533 | E93E2ABB1DCB8F6400F7BEA4 /* Debug */, 534 | E93E2ABC1DCB8F6400F7BEA4 /* Release */, 535 | ); 536 | defaultConfigurationIsVisible = 0; 537 | defaultConfigurationName = Release; 538 | }; 539 | /* End XCConfigurationList section */ 540 | }; 541 | rootObject = E93E2A6F1DCB8ED900F7BEA4 /* Project object */; 542 | } 543 | -------------------------------------------------------------------------------- /XAlign.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /XAlign/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // XAlign 4 | // 5 | // Created by QFish on 03/11/2016. 6 | // Copyright © 2016 QFish. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /XAlign/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // XAlign 4 | // 5 | // Created by QFish on 03/11/2016. 6 | // Copyright © 2016 QFish. 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 | -------------------------------------------------------------------------------- /XAlign/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qfish/XAlign/1513631193d062c7036fce0538eee07edc08e409/XAlign/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /XAlign/Assets.xcassets/AppIcon.appiconset/1024@0.25x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qfish/XAlign/1513631193d062c7036fce0538eee07edc08e409/XAlign/Assets.xcassets/AppIcon.appiconset/1024@0.25x.png -------------------------------------------------------------------------------- /XAlign/Assets.xcassets/AppIcon.appiconset/1024@0.5x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qfish/XAlign/1513631193d062c7036fce0538eee07edc08e409/XAlign/Assets.xcassets/AppIcon.appiconset/1024@0.5x-1.png -------------------------------------------------------------------------------- /XAlign/Assets.xcassets/AppIcon.appiconset/1024@0.5x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qfish/XAlign/1513631193d062c7036fce0538eee07edc08e409/XAlign/Assets.xcassets/AppIcon.appiconset/1024@0.5x.png -------------------------------------------------------------------------------- /XAlign/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 | "size" : "256x256", 35 | "idiom" : "mac", 36 | "filename" : "1024@0.25x.png", 37 | "scale" : "1x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "1024@0.5x-1.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "512x512", 47 | "idiom" : "mac", 48 | "filename" : "1024@0.5x.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "1024.png", 55 | "scale" : "2x" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } -------------------------------------------------------------------------------- /XAlign/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 | Default 511 | 512 | 513 | 514 | 515 | 516 | 517 | Left to Right 518 | 519 | 520 | 521 | 522 | 523 | 524 | Right to Left 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | Default 536 | 537 | 538 | 539 | 540 | 541 | 542 | Left to Right 543 | 544 | 545 | 546 | 547 | 548 | 549 | Right to Left 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 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 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | -------------------------------------------------------------------------------- /XAlign/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | 201611092325 23 | LSApplicationCategoryType 24 | public.app-category.developer-tools 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2016 QFish. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /XAlign/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // XAlign 4 | // 5 | // Created by QFish on 03/11/2016. 6 | // Copyright © 2016 QFish. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : NSViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /XAlign/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // XAlign 4 | // 5 | // Created by QFish on 03/11/2016. 6 | // Copyright © 2016 QFish. 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 | -------------------------------------------------------------------------------- /XAlign/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // XAlign 4 | // 5 | // Created by QFish on 03/11/2016. 6 | // Copyright © 2016 QFish. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | --------------------------------------------------------------------------------