diff --git a/TestXcodeColors/AppDelegate.m b/TestXcodeColors/AppDelegate.m
index 55ab546..02f950b 100644
--- a/TestXcodeColors/AppDelegate.m
+++ b/TestXcodeColors/AppDelegate.m
@@ -1,4 +1,5 @@
#import "AppDelegate.h"
+#import "XcodeColors.h"
// How to apply color formatting to your log statements:
//
@@ -53,6 +54,57 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
NSLog(XCODE_COLORS_ESCAPE @"fg209,57,168;" @"You can supply your own RGB values!" XCODE_COLORS_RESET);
LogBlue(@"Blue text via macro");
+
+ // [self testANSIColors];
+}
+
+- (void)testANSIColors {
+
+ NSLog(@"\n=======Testing ANSI colors=======");
+
+ //These correspond to the TRShellColor values
+ NSArray *colorNames = @[@"Black", @"Red", @"Green", @"Yellow", @"Blue", @"Magenta", @"Cyan", @"White"];
+
+ TRShellAttribute baseAttributes[] = {TRShellAttributeForegroundRegular, TRShellAttributeForegroundLight, TRShellAttributeBackgroundRegular, TRShellAttributeBackgroundLight};
+
+ TRShellColor colorCode;
+ for (NSInteger i = 0; i < 4; i++) {
+
+ TRShellAttribute baseAttribute = baseAttributes[i];
+
+ // Test without reset
+ colorCode = TRShellColorBlack;
+ for (NSString *colorName in colorNames) {
+
+ NSLog(@"%@%lum%@", XCODE_COLORS_ESCAPE, baseAttribute + colorCode++, colorName);
+ }
+
+ NSLog(@"No Attribute");
+
+
+ //Test with reset
+ colorCode = TRShellColorBlack;
+ for (NSString *colorName in colorNames) {
+
+ NSLog(@"%@%lum%@%@", XCODE_COLORS_ESCAPE, baseAttribute + colorCode++, colorName, XCODE_COLORS_RESET);
+ }
+
+ NSLog(@"No Attribute");
+ }
+
+ // Test setting both background and foreground
+ colorCode = TRShellColorBlack;
+ NSInteger count = 0;
+
+ for (NSString *colorName in colorNames) {
+
+ TRShellColor bgColorCode = [colorNames count] - (1 + count++);
+ NSString *bgColorName = colorNames[bgColorCode];
+ NSLog(@"%@%lu;%lum%@-bg%@%@", XCODE_COLORS_ESCAPE, TRShellAttributeForegroundRegular + colorCode, TRShellAttributeBackgroundRegular + bgColorCode, colorName, bgColorName,XCODE_COLORS_RESET);
+ colorCode++;
+ }
+
+ NSLog(@"No Attribute");
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
diff --git a/XcodeColors/Info.plist b/XcodeColors/Info.plist
index 7a237b5..fbc387f 100644
--- a/XcodeColors/Info.plist
+++ b/XcodeColors/Info.plist
@@ -12,13 +12,6 @@
ru.DeepIT.${PRODUCT_NAME}
CFBundleInfoDictionaryVersion
6.0
- DVTPlugInCompatibilityUUIDs
-
- 63FC1C47-140D-42B0-BB4D-A10B2D225574
- 37B30044-3B14-46BA-ABAA-F01000C27B63
- 640F884E-CE55-4B40-87C0-8869546CAB7A
- A2E4D43F-41F4-4FB9-BB94-7177011C9AED
-
CFBundleName
${PRODUCT_NAME}
CFBundlePackageType
@@ -29,6 +22,14 @@
????
CFBundleVersion
109
+ DVTPlugInCompatibilityUUIDs
+
+ 63FC1C47-140D-42B0-BB4D-A10B2D225574
+ 37B30044-3B14-46BA-ABAA-F01000C27B63
+ 640F884E-CE55-4B40-87C0-8869546CAB7A
+ A2E4D43F-41F4-4FB9-BB94-7177011C9AED
+ AD68E85B-441B-4301-B564-A45E4919A6AD
+
LoadAtLaunch
NSPrincipalClass
@@ -44,13 +45,13 @@
com.apple.dt.Xcode
- XCGCReady
-
- XCPluginHasUI
-
XC4Compatible
XC5Compatible
+ XCGCReady
+
+ XCPluginHasUI
+
diff --git a/XcodeColors/XcodeColors.h b/XcodeColors/XcodeColors.h
index 27d4095..da62215 100644
--- a/XcodeColors/XcodeColors.h
+++ b/XcodeColors/XcodeColors.h
@@ -8,6 +8,81 @@
#import
+typedef NS_OPTIONS(NSUInteger, TRShellColor) {
+
+ TRShellColorBlack = 0,
+ TRShellColorRed,
+ TRShellColorGreen,
+ TRShellColorYellow,
+ TRShellColorBlue,
+ TRShellColorMagenta,
+ TRShellColorCyan,
+ TRShellColorWhite
+};
+
+typedef NS_ENUM(NSInteger, TRShellAttribute) {
+
+ TRShellAttributeResetAll = 0,
+ /* TRShellAttributeBold = 1,
+ TRShellAttributeDim = 2,
+ TRShellAttributeUnderlined = 4,
+ TRShellAttributeBlink = 5,
+ TRShellAttributeInvert = 7,
+ TRShellAttributeHidden = 8,
+
+ TRShellAttributeResetBold = 21,
+ TRShellAttributeResetDim = 22,
+ TRShellAttributeResetUnderlined = 24,
+ TRShellAttributeResetBlink = 25,
+ TRShellAttributeResetReverse = 27,
+ TRShellAttributeResetHidden = 28,
+ */
+
+ TRShellAttributeForegroundRegular = 30,
+ TRShellAttributeForegroundBlack = TRShellAttributeForegroundRegular + TRShellColorBlack,
+ TRShellAttributeForegroundRed = TRShellAttributeForegroundRegular + TRShellColorRed,
+ TRShellAttributeForegroundGreen = TRShellAttributeForegroundRegular + TRShellColorGreen,
+ TRShellAttributeForegroundYellow = TRShellAttributeForegroundRegular + TRShellColorYellow,
+ TRShellAttributeForegroundBlue = TRShellAttributeForegroundRegular + TRShellColorBlue,
+ TRShellAttributeForegroundMagenta = TRShellAttributeForegroundRegular + TRShellColorMagenta,
+ TRShellAttributeForegroundCyan = TRShellAttributeForegroundRegular + TRShellColorCyan,
+ TRShellAttributeForegroundLightGray = TRShellAttributeForegroundRegular + TRShellColorWhite,
+
+ TRShellAttributeForegroundDefault = 39,
+
+ TRShellAttributeForegroundLight = 90,
+ TRShellAttributeForegroundDarkGray = TRShellAttributeForegroundLight + TRShellColorBlack,
+ TRShellAttributeForegroundLightRed = TRShellAttributeForegroundLight + TRShellColorRed,
+ TRShellAttributeForegroundLightGreen = TRShellAttributeForegroundLight + TRShellColorGreen,
+ TRShellAttributeForegroundLightYellow = TRShellAttributeForegroundLight + TRShellColorYellow,
+ TRShellAttributeForegroundLightBlue = TRShellAttributeForegroundLight + TRShellColorBlue,
+ TRShellAttributeForegroundLightMagenta = TRShellAttributeForegroundLight + TRShellColorMagenta,
+ TRShellAttributeForegroundLightCyan = TRShellAttributeForegroundLight + TRShellColorCyan,
+ TRShellAttributeForegroundWhite = TRShellAttributeForegroundLight + TRShellColorWhite,
+
+ TRShellAttributeBackgroundRegular = 40,
+ TRShellAttributeBackgroundBlack = TRShellAttributeBackgroundRegular + TRShellColorBlack,
+ TRShellAttributeBackgroundRed = TRShellAttributeBackgroundRegular + TRShellColorRed,
+ TRShellAttributeBackgroundGreen = TRShellAttributeBackgroundRegular + TRShellColorGreen,
+ TRShellAttributeBackgroundYellow = TRShellAttributeBackgroundRegular + TRShellColorYellow,
+ TRShellAttributeBackgroundBlue = TRShellAttributeBackgroundRegular + TRShellColorBlue,
+ TRShellAttributeBackgroundMagenta = TRShellAttributeBackgroundRegular + TRShellColorMagenta,
+ TRShellAttributeBackgroundCyan = TRShellAttributeBackgroundRegular + TRShellColorCyan,
+ TRShellAttributeBackgroundLightGray = TRShellAttributeBackgroundRegular + TRShellColorWhite,
+
+ TRShellAttributeBackgroundDefault = 49,
+
+ TRShellAttributeBackgroundLight = 100,
+ TRShellAttributeBackgroundDarkGray = TRShellAttributeBackgroundLight + TRShellColorBlack,
+ TRShellAttributeBackgroundLightRed = TRShellAttributeBackgroundLight + TRShellColorRed,
+ TRShellAttributeBackgroundLightGreen = TRShellAttributeBackgroundLight + TRShellColorGreen,
+ TRShellAttributeBackgroundLightYellow = TRShellAttributeBackgroundLight + TRShellColorYellow,
+ TRShellAttributeBackgroundLightBlue = TRShellAttributeBackgroundLight + TRShellColorBlue,
+ TRShellAttributeBackgroundLightMagenta = TRShellAttributeBackgroundLight + TRShellColorMagenta,
+ TRShellAttributeBackgroundLightCyan = TRShellAttributeBackgroundLight + TRShellColorCyan,
+ TRShellAttributeBackgroundWhite = TRShellAttributeBackgroundLight + TRShellColorWhite,
+};
+
@interface XcodeColors_NSTextStorage : NSTextStorage
- (void)fixAttributesInRange:(NSRange)aRange;
diff --git a/XcodeColors/XcodeColors.m b/XcodeColors/XcodeColors.m
index 709b48b..de81cb7 100644
--- a/XcodeColors/XcodeColors.m
+++ b/XcodeColors/XcodeColors.m
@@ -112,37 +112,30 @@ void ApplyANSIColors(NSTextStorage *textStorage, NSRange textStorageRange, NSStr
BOOL reset = !stop && (stop = [component hasPrefix:@";"]);
BOOL fg = !stop && (stop = [component hasPrefix:@"fg"]);
BOOL bg = !stop && (stop = [component hasPrefix:@"bg"]);
-
+ BOOL ansi = !stop;
+
BOOL resetFg = fg && [component hasPrefix:@"fg;"];
BOOL resetBg = bg && [component hasPrefix:@"bg;"];
-
+
if (reset)
{
- // Reset attributes
+ // reset sequence length (";")
+ colorCodeSeqLength = 1;
+
+ // Reset attributes
[attrs removeObjectForKey:NSForegroundColorAttributeName];
[attrs removeObjectForKey:NSBackgroundColorAttributeName];
-
- // Mark the range of the sequence (escape sequence + reset color sequence).
- NSRange seqRange = (NSRange){
- .location = componentRange.location - [escapeSeq length],
- .length = 1 + [escapeSeq length],
- };
- [seqRanges addObject:[NSValue valueWithRange:seqRange]];
}
else if (resetFg || resetBg)
{
+ // reset color sequence length (@"xx;")
+ colorCodeSeqLength = 3;
+
// Reset attributes
if (resetFg)
[attrs removeObjectForKey:NSForegroundColorAttributeName];
else
[attrs removeObjectForKey:NSBackgroundColorAttributeName];
-
- // Mark the range of the sequence (escape sequence + reset color sequence).
- NSRange seqRange = (NSRange){
- .location = componentRange.location - [escapeSeq length],
- .length = 3 + [escapeSeq length],
- };
- [seqRanges addObject:[NSValue valueWithRange:seqRange]];
}
else if (fg || bg)
{
@@ -222,30 +215,152 @@ void ApplyANSIColors(NSTextStorage *textStorage, NSRange textStorageRange, NSStr
{
[attrs setObject:color forKey:NSBackgroundColorAttributeName];
}
-
- //NSString *realString = [component substringFromIndex:colorCodeSeqLength];
-
- // Mark the range of the entire sequence (escape sequence + color code sequence).
- NSRange seqRange = (NSRange){
- .location = componentRange.location - [escapeSeq length],
- .length = colorCodeSeqLength + [escapeSeq length],
- };
- [seqRanges addObject:[NSValue valueWithRange:seqRange]];
- }
+ }
else
{
// Wasn't able to parse a color code
-
- [attrs removeObjectForKey:NSForegroundColorAttributeName];
- [attrs removeObjectForKey:NSBackgroundColorAttributeName];
-
- NSRange seqRange = (NSRange){
- .location = componentRange.location - [escapeSeq length],
- .length = [escapeSeq length],
- };
- [seqRanges addObject:[NSValue valueWithRange:seqRange]];
+ colorCodeSeqLength = 0;
+
+ // Reset attributes
+ [attrs removeObjectForKey:NSForegroundColorAttributeName];
+ [attrs removeObjectForKey:NSBackgroundColorAttributeName];
}
}
+ else if (ansi) {
+
+ NSUInteger endIndex = [component rangeOfString:@"m"].location;
+
+ if (endIndex == NSNotFound) {
+
+ // Wasn't able to parse a color code
+ colorCodeSeqLength = 0;
+ }
+
+ if (endIndex == 0) {
+
+ // empty color sequence ("m")
+ colorCodeSeqLength = 1;
+ }
+ else {
+
+ colorCodeSeqLength = endIndex + 1;
+
+ NSString *attrString = [component substringWithRange:NSMakeRange(0, endIndex)];
+
+ NSString * const kTRShellAttributesSeparator = @";";
+
+ NSArray *attributes = [attrString componentsSeparatedByString:kTRShellAttributesSeparator];
+
+ NSColor *foregroundColor = nil, *backgroundColor = nil;
+ BOOL clearForeground = NO, clearBackground = NO;
+
+ for (NSString *attributeStr in attributes) {
+
+ TRShellAttribute attribute = [attributeStr integerValue];
+
+ switch (attribute) {
+
+ /* reset cases */
+
+ case TRShellAttributeResetAll:
+ foregroundColor = backgroundColor = nil;
+ clearForeground = clearBackground = YES;
+ break;
+
+ case TRShellAttributeForegroundDefault:
+ foregroundColor = nil;
+ clearForeground = YES;
+ break;
+
+ case TRShellAttributeBackgroundDefault:
+ backgroundColor = nil;
+ clearBackground = YES;
+ break;
+
+ /* foreground color cases */
+
+ case TRShellAttributeForegroundBlack:
+ case TRShellAttributeForegroundRed:
+ case TRShellAttributeForegroundGreen:
+ case TRShellAttributeForegroundYellow:
+ case TRShellAttributeForegroundBlue:
+ case TRShellAttributeForegroundMagenta:
+ case TRShellAttributeForegroundCyan:
+ case TRShellAttributeForegroundLightGray:
+ {
+ TRShellColor colorCode = attribute - TRShellAttributeForegroundRegular;
+ foregroundColor = colorForShellColor(colorCode, NO);
+ break;
+ }
+
+ case TRShellAttributeForegroundDarkGray:
+ case TRShellAttributeForegroundLightRed:
+ case TRShellAttributeForegroundLightGreen:
+ case TRShellAttributeForegroundLightYellow:
+ case TRShellAttributeForegroundLightBlue:
+ case TRShellAttributeForegroundLightMagenta:
+ case TRShellAttributeForegroundLightCyan:
+ case TRShellAttributeForegroundWhite:
+ {
+ TRShellColor colorCode = attribute - TRShellAttributeForegroundLight;
+ foregroundColor = colorForShellColor(colorCode, YES);
+ break;
+ }
+
+ case TRShellAttributeBackgroundBlack:
+ case TRShellAttributeBackgroundRed:
+ case TRShellAttributeBackgroundGreen:
+ case TRShellAttributeBackgroundYellow:
+ case TRShellAttributeBackgroundBlue:
+ case TRShellAttributeBackgroundMagenta:
+ case TRShellAttributeBackgroundCyan:
+ case TRShellAttributeBackgroundLightGray:
+ {
+ TRShellColor colorCode = attribute - TRShellAttributeBackgroundRegular;
+ backgroundColor = colorForShellColor(colorCode, NO);
+ break;
+ }
+
+ case TRShellAttributeBackgroundDarkGray:
+ case TRShellAttributeBackgroundLightRed:
+ case TRShellAttributeBackgroundLightGreen:
+ case TRShellAttributeBackgroundLightYellow:
+ case TRShellAttributeBackgroundLightBlue:
+ case TRShellAttributeBackgroundLightMagenta:
+ case TRShellAttributeBackgroundLightCyan:
+ case TRShellAttributeBackgroundWhite:
+ {
+ TRShellColor colorCode = attribute - TRShellAttributeBackgroundLight;
+ backgroundColor = colorForShellColor(colorCode, YES);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ }
+
+ if (clearForeground) {
+ [attrs removeObjectForKey:NSForegroundColorAttributeName];
+ }
+ if (clearBackground) {
+ [attrs removeObjectForKey:NSBackgroundColorAttributeName];
+ }
+ if (foregroundColor) {
+ [attrs setObject:foregroundColor forKey:NSForegroundColorAttributeName];
+ }
+ if (backgroundColor) {
+ [attrs setObject:backgroundColor forKey:NSBackgroundColorAttributeName];
+ }
+ }
+ }
+
+ NSRange seqRange = (NSRange){
+ .location = componentRange.location - [escapeSeq length],
+ .length = colorCodeSeqLength + [escapeSeq length],
+ };
+ [seqRanges addObject:[NSValue valueWithRange:seqRange]];
}
componentRange.length = [component length];
@@ -275,6 +390,94 @@ void ApplyANSIColors(NSTextStorage *textStorage, NSRange textStorageRange, NSStr
}
}
+NSColor *colorForShellColor(TRShellColor colorCode, BOOL light) {
+
+ // These colors are taken from the Terminal.app default preferences.
+
+ switch (colorCode) {
+
+ case TRShellColorBlack:
+
+ if (!light) {
+ return [NSColor blackColor];
+ }
+ else {
+ return [NSColor colorWithCalibratedRed:0.326 green:0.326 blue:0.326 alpha:1.000];
+ }
+ break;
+
+ case TRShellColorRed:
+
+ if (!light) {
+ return [NSColor colorWithDeviceRed:0.522 green:0.000 blue:0.009 alpha:1.000];
+ }
+ else {
+ return [NSColor colorWithDeviceRed:0.863 green:0.000 blue:0.021 alpha:1.000];
+ }
+ break;
+
+ case TRShellColorGreen:
+
+ if (!light) {
+ return [NSColor colorWithCalibratedRed:0.079 green:0.602 blue:0.009 alpha:1.000];
+ }
+ else {
+ return [NSColor colorWithCalibratedRed:0.110 green:0.839 blue:0.017 alpha:1.000];
+ }
+ break;
+
+ case TRShellColorYellow:
+
+ if (!light) {
+ return [NSColor colorWithCalibratedRed:0.530 green:0.540 blue:0.017 alpha:1.000];
+ }
+ else {
+ return [NSColor colorWithCalibratedRed:0.877 green:0.892 blue:0.036 alpha:1.000];
+ }
+ break;
+
+ case TRShellColorBlue:
+
+ if (!light) {
+ return [NSColor colorWithCalibratedRed:0.000 green:0.000 blue:0.639 alpha:1.000];
+ }
+ else {
+ return [NSColor colorWithCalibratedRed:0.000 green:0.000 blue:0.998 alpha:1.000];
+ }
+ break;
+
+ case TRShellColorMagenta:
+
+ if (!light) {
+ return [NSColor colorWithCalibratedRed:0.630 green:0.000 blue:0.640 alpha:1.000];
+ }
+ else {
+ return [NSColor colorWithCalibratedRed:0.862 green:0.000 blue:0.875 alpha:1.000];
+ }
+ break;
+
+ case TRShellColorCyan:
+
+ if (!light) {
+ return [NSColor colorWithCalibratedRed:0.075 green:0.589 blue:0.639 alpha:1.000];
+ }
+ else {
+ return [NSColor colorWithCalibratedRed:0.113 green:0.885 blue:0.875 alpha:1.000];
+ }
+ break;
+
+ case TRShellColorWhite:
+
+ if (!light) {
+ return [NSColor colorWithCalibratedRed:0.697 green:0.697 blue:0.697 alpha:1.000];
+ }
+ else {
+ return [NSColor colorWithCalibratedRed:0.876 green:0.876 blue:0.876 alpha:1.000];
+ }
+ break;
+ }
+}
+
- (void)fixAttributesInRange:(NSRange)aRange
{
// This method "overrides" the method within NSTextStorage.