forked from robbiehanson/XcodeColors
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathXcodeColors.m
More file actions
182 lines (146 loc) · 6.63 KB
/
Copy pathXcodeColors.m
File metadata and controls
182 lines (146 loc) · 6.63 KB
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
//
// XcodeColors.m
// XcodeColors
//
// Created by Uncle MiF on 9/13/10.
// Copyright 2010 Deep IT. All rights reserved.
//
#import "XcodeColors.h"
#import <objc/runtime.h>
#define XCODE_COLORS "XcodeColors"
// How to apply color formatting to your log statements:
//
// To set the foreground color:
// Insert the ESCAPE_SEQ into your string, followed by "fg124,12,255;" where r=124, g=12, b=255.
//
// To set the background color:
// Insert the ESCAPE_SEQ into your string, followed by "bg12,24,36;" where r=12, g=24, b=36.
//
// To reset the foreground color (to default value):
// Insert the ESCAPE_SEQ into your string, followed by "fg;"
//
// To reset the background color (to default value):
// Insert the ESCAPE_SEQ into your string, followed by "bg;"
//
// To reset the foreground and background color (to default values) in one operation:
// Insert the ESCAPE_SEQ into your string, followed by ";"
//
//
// Feel free to copy the define statements below into your code.
// <COPY ME>
#define XCODE_COLORS_ESCAPE @"\033["
#define XCODE_COLORS_RESET_FG XCODE_COLORS_ESCAPE @"fg;" // Clear any foreground color
#define XCODE_COLORS_RESET_BG XCODE_COLORS_ESCAPE @"bg;" // Clear any background color
#define XCODE_COLORS_RESET XCODE_COLORS_ESCAPE @";" // Clear any foreground or background color
// </COPY ME>
static IMP IMP_NSTextStorage_fixAttributesInRange = nil;
@implementation XcodeColors_NSTextStorage
void ApplyANSIColors(NSTextStorage *textStorage, NSRange textStorageRange, NSString *escapeSeq)
{
NSString *affectedString = [[textStorage string] substringWithRange:textStorageRange];
NSDictionary *errorAttributes = @{NSForegroundColorAttributeName:[NSColor colorWithCalibratedRed:0.717 green:0.000 blue:0.028 alpha:1.000]};
NSDictionary *goodAttributes = @{NSForegroundColorAttributeName:[NSColor colorWithCalibratedRed:0.186 green:0.582 blue:0.017 alpha:1.000]};
NSDictionary *debugAttributes = @{NSForegroundColorAttributeName:[NSColor colorWithCalibratedRed:0.981 green:0.491 blue:0.118 alpha:1.000]};
// Apply red color to strings looking like ***this***.
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\*\\*\\*.*?\\*\\*\\*"
options:(NSRegularExpressionCaseInsensitive |
NSRegularExpressionDotMatchesLineSeparators)
error:&error];
NSArray *matches = [regex matchesInString:affectedString options:0 range:NSMakeRange(0, affectedString.length)];
for (NSTextCheckingResult *match in matches) {
NSRange matchRange = match.range;
[textStorage addAttributes:errorAttributes range:matchRange];
}
// Apply green color to strings looking like ---this---
error = NULL;
regex = [NSRegularExpression regularExpressionWithPattern:@"---.*?---"
options:(NSRegularExpressionCaseInsensitive |
NSRegularExpressionDotMatchesLineSeparators)
error:&error];
matches = [regex matchesInString:affectedString options:0 range:NSMakeRange(0, affectedString.length)];
for (NSTextCheckingResult *match in matches) {
NSRange matchRange = match.range;
[textStorage addAttributes:goodAttributes range:matchRange];
}
// Apply orange color to strings looking like :::this:::
error = NULL;
regex = [NSRegularExpression regularExpressionWithPattern:@":::.*?:::"
options:(NSRegularExpressionCaseInsensitive |
NSRegularExpressionDotMatchesLineSeparators)
error:&error];
matches = [regex matchesInString:affectedString options:0 range:NSMakeRange(0, affectedString.length)];
for (NSTextCheckingResult *match in matches) {
NSRange matchRange = match.range;
[textStorage addAttributes:debugAttributes range:matchRange];
}
}
- (void)fixAttributesInRange:(NSRange)aRange
{
// This method "overrides" the method within NSTextStorage.
// First we invoke the actual NSTextStorage method.
// This allows it to do any normal processing.
IMP_NSTextStorage_fixAttributesInRange(self, _cmd, aRange);
// Then we scan for our special escape sequences, and apply desired color attributes.
char *xcode_colors = getenv(XCODE_COLORS);
if (xcode_colors && (strcmp(xcode_colors, "YES") == 0))
{
ApplyANSIColors(self, aRange, XCODE_COLORS_ESCAPE);
}
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation XcodeColors
IMP ReplaceInstanceMethod(Class sourceClass, SEL sourceSel, Class destinationClass, SEL destinationSel)
{
if (!sourceSel || !sourceClass || !destinationClass)
{
NSLog(@"XcodeColors: Missing parameter to ReplaceInstanceMethod");
return nil;
}
if (!destinationSel)
destinationSel = sourceSel;
Method sourceMethod = class_getInstanceMethod(sourceClass, sourceSel);
if (!sourceMethod)
{
NSLog(@"XcodeColors: Unable to get sourceMethod");
return nil;
}
IMP prevImplementation = method_getImplementation(sourceMethod);
Method destinationMethod = class_getInstanceMethod(destinationClass, destinationSel);
if (!destinationMethod)
{
NSLog(@"XcodeColors: Unable to get destinationMethod");
return nil;
}
IMP newImplementation = method_getImplementation(destinationMethod);
if (!newImplementation)
{
NSLog(@"XcodeColors: Unable to get newImplementation");
return nil;
}
method_setImplementation(sourceMethod, newImplementation);
return prevImplementation;
}
+ (void)load
{
NSLog(@"XcodeColors: %@ (v10.1)", NSStringFromSelector(_cmd));
char *xcode_colors = getenv(XCODE_COLORS);
if (xcode_colors && (strcmp(xcode_colors, "YES") != 0))
return;
IMP_NSTextStorage_fixAttributesInRange =
ReplaceInstanceMethod([NSTextStorage class], @selector(fixAttributesInRange:),
[XcodeColors_NSTextStorage class], @selector(fixAttributesInRange:));
setenv(XCODE_COLORS, "YES", 0);
}
+ (void)pluginDidLoad:(id)xcodeDirectCompatibility
{
NSLog(@"XcodeColors: %@", NSStringFromSelector(_cmd));
}
- (void)registerLaunchSystemDescriptions
{
NSLog(@"XcodeColors: %@", NSStringFromSelector(_cmd));
}
@end