Skip to content

Commit

Permalink
Add LSLog-XCode
Browse files Browse the repository at this point in the history
  • Loading branch information
tinymind committed Dec 18, 2015
1 parent c248640 commit b3f0c84
Show file tree
Hide file tree
Showing 24 changed files with 2,196 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ DerivedData
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
#Pods/

# Mac
#
.DS_Store
Binary file added LSLog-XCode.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
347 changes: 347 additions & 0 deletions LSLog-XCode.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 92 additions & 0 deletions LSLog-XCode.xcodeproj/xcshareddata/xcschemes/LSLog-XCode.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "2.0">
<BuildAction
parallelizeBuildables = "NO"
buildImplicitDependencies = "NO">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B15C7B5E1C197A8300C92958"
BuildableName = "LSLog-XCode.xcplugin"
BlueprintName = "LSLog-XCode"
ReferencedContainer = "container:LSLog-XCode.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8966AFCA173EB7BF004150C0"
BuildableName = "LSLog-XCodeTests.xctest"
BlueprintName = "LSLog-XCodeTests"
ReferencedContainer = "container:LSLog-XCode.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "NO"
debugXPCServices = "NO"
debugServiceExtension = "internal"
allowLocationSimulation = "NO"
viewDebuggingEnabled = "No">
<PathRunnable
runnableDebuggingMode = "0"
BundleIdentifier = "com.apple.dt.Xcode"
FilePath = "/Applications/Xcode.app">
</PathRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B15C7B5E1C197A8300C92958"
BuildableName = "LSLog-XCode.xcplugin"
BlueprintName = "LSLog-XCode"
ReferencedContainer = "container:LSLog-XCode.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
25 changes: 25 additions & 0 deletions LSLog-XCode/Category/NSObject+LSLog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// NSObject+LSLog.h
// LSLog-XCode
//
// Created by lslin on 15/12/10.
// Copyright © 2015年 lessfun.com. All rights reserved.
//

#import <AppKit/AppKit.h>

@class LSIDEConsoleArea;

@interface NSObject (LSLog)

@property (nonatomic, strong) NSTextView *consoleTextView;
@property (nonatomic, strong) LSIDEConsoleArea *consoleArea;
@property (nonatomic, assign) NSUInteger logLevel;

+ (void)pluginDidLoad:(NSBundle *)plugin;

- (NSSearchField *)ls_getFilterField;
- (void)ls_updateItemAttribute:(id)item;
- (NSString *)ls_hash;

@end
140 changes: 140 additions & 0 deletions LSLog-XCode/Category/NSObject+LSLog.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//
// NSObject+LSLog.m
// LSLog-XCode
//
// Created by lslin on 15/12/10.
// Copyright © 2015年 lessfun.com. All rights reserved.
//


#import "NSObject+LSLog.h"
#import "LSLog.h"
#import "LSLogSettings.h"
#import "LSIDEConsoleArea.h"

#import <objc/runtime.h>

static const void *kLSIDEConsoleTextViewKey;
static const void *kLSIDEConsoleAreaKey;
static const void *kLSLogLevelKey;

@implementation NSObject (LSLog)


+ (void)pluginDidLoad:(NSBundle *)plugin
{
NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
if ([currentApplicationName isEqual:@"Xcode"]) {
[LSLog sharedPlugin];
}
}

- (void)setConsoleTextView:(NSTextView *)consoleTextView
{
objc_setAssociatedObject(self, &kLSIDEConsoleTextViewKey, consoleTextView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSTextView *)consoleTextView
{
return objc_getAssociatedObject(self, &kLSIDEConsoleTextViewKey);
}

- (void)setConsoleArea:(LSIDEConsoleArea *)consoleArea
{
objc_setAssociatedObject(self, &kLSIDEConsoleAreaKey, consoleArea, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (LSIDEConsoleArea *)consoleArea
{
return objc_getAssociatedObject(self, &kLSIDEConsoleAreaKey);
}

- (void)setLogLevel:(NSUInteger)loglevel
{
objc_setAssociatedObject(self, &kLSLogLevelKey, @(loglevel), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSUInteger)logLevel
{
return [objc_getAssociatedObject(self, &kLSLogLevelKey) unsignedIntegerValue];
}

- (NSSearchField *)ls_getFilterField {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
if (![self respondsToSelector:@selector(scopeBarView)]) {
return nil;
}

NSView *scopeBarView = [self performSelector:@selector(scopeBarView) withObject:nil];
return [scopeBarView viewWithTag:LSLogViewTagFilterField];
#pragma clang diagnositc pop
}

- (void)ls_updateItemAttribute:(id)item {
NSString *logText = [item valueForKey:@"content"];
if (!logText.length) {
return;
}

if ([[item valueForKey:@"error"] boolValue] || [logText hasPrefix:@"error"]) {
logText = [self formatStringWithString:logText fgColor:[LSLogSettings defaultSettings].fgColorError];
[item setValue:logText forKey:@"content"];
return;
}

if (![[item valueForKey:@"output"] boolValue] || [[item valueForKey:@"outputRequestedByUser"] boolValue]) {
return;
}

NSString *content = logText;
if ([logText rangeOfString:[LSLogSettings defaultSettings].logLevelPrefixError].location != NSNotFound) {
[item setLogLevel:LSLogLevelError];
content = [self formatStringWithString:logText fgColor:[LSLogSettings defaultSettings].fgColorError];
} else if ([logText rangeOfString:[LSLogSettings defaultSettings].logLevelPrefixWarn].location != NSNotFound) {
[item setLogLevel:LSLogLevelWarn];
content = [self formatStringWithString:logText fgColor:[LSLogSettings defaultSettings].fgColorWarn];
} else if ([logText rangeOfString:[LSLogSettings defaultSettings].logLevelPrefixInfo].location != NSNotFound) {
[item setLogLevel:LSLogLevelInfo];
content = [self formatStringWithString:logText fgColor:[LSLogSettings defaultSettings].fgColorInfo];
} else if ([logText rangeOfString:[LSLogSettings defaultSettings].logLevelPrefixVerbose].location != NSNotFound) {
[item setLogLevel:LSLogLevelVerbose];
content = [self formatStringWithString:logText fgColor:[LSLogSettings defaultSettings].fgColorVerbose];
} else {
static NSArray *normalErrors = nil;
if (normalErrors == nil) {
normalErrors = @[@"Terminating app due to uncaught exception",
@"unrecognized selector sent to",
@"Assertion failure in"
];
}
for (NSString *err in normalErrors) {
if ([logText rangeOfString:err].location != NSNotFound) {
content = [self formatStringWithString:logText fgColor:[LSLogSettings defaultSettings].fgColorError];
break;
}
}
}

[item setValue:content forKey:@"content"];
}

- (NSString *)ls_hash {
return [NSString stringWithFormat:@"%lx", (long)self];
}

#pragma mark - Private

- (NSString *)stringFromColor:(NSColor *)color {
return [NSString stringWithFormat:@"%d,%d,%d", (int)(color.redComponent * 255), (int)(color.greenComponent * 255), (int)(color.blueComponent * 255)];
}

- (NSString *)formatStringWithString:(NSString *)str fgColor:(NSColor *)fgColor {
return [NSString stringWithFormat:(XCODE_COLORS_ESCAPE @"fg%@;%@" XCODE_COLORS_RESET_FG), [self stringFromColor:fgColor], str];
}

//- (NSString *)formatStringWithString:(NSString *)str fgColor:(NSColor *)fgColor bgColor:(NSColor *)bgColor {
// return [NSString stringWithFormat:@"%@fg%@;bg%@;%@%@", XCODE_COLORS_ESCAPE, [self stringFromColor:fgColor], [self stringFromColor:bgColor], str, XCODE_COLORS_RESET];
//}

@end
18 changes: 18 additions & 0 deletions LSLog-XCode/Category/NSObject+LSSwizzle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// NSObject+LSSwizzle.h
// LSLog-XCode
//
// Created by lslin on 15/12/11.
// Copyright © 2015年 lessfun.com. All rights reserved.
//

#import <Foundation/Foundation.h>

IMP ls_replaceOriginalClassMethod(Class origClass, Class altClass, SEL sel);

@interface NSObject (LSSwizzle)

+ (BOOL)ls_swizzleOriginalMethod:(SEL)origSel withAltMethod:(SEL)altSel;
+ (IMP)ls_replaceOriginalClass:(Class)origClass withAltClass:(Class)altClass method:(SEL)sel;

@end
47 changes: 47 additions & 0 deletions LSLog-XCode/Category/NSObject+LSSwizzle.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// NSObject+LSSwizzle.m
// LSLog-XCode
//
// Created by lslin on 15/12/11.
// Copyright © 2015年 lessfun.com. All rights reserved.
//

#import "NSObject+LSSwizzle.h"

#import <objc/runtime.h>

@implementation NSObject (LSSwizzle)

+ (BOOL)ls_swizzleOriginalMethod:(SEL)origSel withAltMethod:(SEL)altSel {
Method origMethod = class_getInstanceMethod(self, origSel);
if (!origMethod) {
return NO;
}

Method altMethod = class_getInstanceMethod(self, altSel);
if (!altMethod) {
return NO;
}

class_addMethod(self,
origSel,
class_getMethodImplementation(self, origSel),
method_getTypeEncoding(origMethod));
class_addMethod(self,
altSel,
class_getMethodImplementation(self, altSel),
method_getTypeEncoding(altMethod));

method_exchangeImplementations(class_getInstanceMethod(self, origSel), class_getInstanceMethod(self, altSel));
return YES;
}

+ (IMP)ls_replaceOriginalClass:(Class)origClass withAltClass:(Class)altClass method:(SEL)sel {
Method oldMethod = class_getInstanceMethod(origClass, sel);
IMP oldIMP = method_getImplementation(oldMethod);
IMP newIMP = class_getMethodImplementation(altClass, sel);
method_setImplementation(oldMethod, newIMP);
return oldIMP;
}

@end
15 changes: 15 additions & 0 deletions LSLog-XCode/Category/NSTextStorage+LSLog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// NSTextStorage+LSLog.h
// LSLog-XCode
//
// Created by lslin on 15/12/10.
// Copyright © 2015年 lessfun.com. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@interface NSTextStorage (LSLog)

- (void)ls_fixAttributesInRange:(NSRange)range;

@end
Loading

0 comments on commit b3f0c84

Please sign in to comment.