├── .gitignore ├── Screenshots └── LinkedLog.png ├── .travis.yml ├── JWLinkedLog ├── pch_file.xctemplate │ ├── TemplateIcon.png │ ├── TemplateIcon@2x.png │ ├── TemplateInfo.plist │ └── ___FILEBASENAME___.pch ├── DVTSimpleSerialization-Protocol.h ├── JRSwizzle.h ├── DTXcodeUtils │ ├── Classes │ │ ├── DTXcodeUtils.h │ │ └── DTXcodeUtils.m │ └── XcodeHeaders │ │ └── DTXcodeHeaders.h ├── DVTDocumentLocation.h ├── JWLinkedLog.h ├── NSTextStorage+findInFiles.h ├── Info.plist ├── DVTSourceExpression.h ├── DVTTextDocumentLocation.h ├── PrefixHeader.pch ├── NSTextStorage+findInFiles.m ├── JRSwizzle.m └── JWLinkedLog.m ├── LinkedLog.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── LinkedLog.xccheckout ├── xcshareddata │ └── xcschemes │ │ └── JWLinkedLog.xcscheme └── project.pbxproj ├── LICENSE.txt └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | DerivedData 3 | xcuserdata 4 | -------------------------------------------------------------------------------- /Screenshots/LinkedLog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julian-weinert/LinkedLog/HEAD/Screenshots/LinkedLog.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | 3 | # branch whitelist 4 | # branches: 5 | # only: 6 | # - master 7 | -------------------------------------------------------------------------------- /JWLinkedLog/pch_file.xctemplate/TemplateIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julian-weinert/LinkedLog/HEAD/JWLinkedLog/pch_file.xctemplate/TemplateIcon.png -------------------------------------------------------------------------------- /JWLinkedLog/pch_file.xctemplate/TemplateIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julian-weinert/LinkedLog/HEAD/JWLinkedLog/pch_file.xctemplate/TemplateIcon@2x.png -------------------------------------------------------------------------------- /LinkedLog.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /JWLinkedLog/DVTSimpleSerialization-Protocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generated by class-dump 3.3.4 (64 bit). 3 | * 4 | * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2011 by Steve Nygard. 5 | */ 6 | 7 | @protocol DVTSimpleSerialization 8 | - (void)dvt_writeToSerializer:(id)arg1; 9 | - (id)dvt_initFromDeserializer:(id)arg1; 10 | @end 11 | 12 | -------------------------------------------------------------------------------- /JWLinkedLog/JRSwizzle.h: -------------------------------------------------------------------------------- 1 | // JRSwizzle.h semver:1.0 2 | // Copyright (c) 2007-2011 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/MIT 4 | // https://github.com/rentzsch/jrswizzle 5 | 6 | #import 7 | 8 | @interface NSObject (JRSwizzle) 9 | 10 | + (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_; 11 | + (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /JWLinkedLog/DTXcodeUtils/Classes/DTXcodeUtils.h: -------------------------------------------------------------------------------- 1 | 2 | @class DVTSourceTextView; 3 | @class DVTTextStorage; 4 | @class IDEEditor; 5 | @class IDESourceCodeEditor; 6 | @class IDEEditorArea; 7 | @class IDESourceCodeDocument; 8 | @class IDEEditorContext; 9 | @class IDEWorkspaceWindowController; 10 | 11 | @interface DTXcodeUtils : NSObject 12 | + (NSWindow *)currentWindow; 13 | + (NSResponder *)currentWindowResponder; 14 | + (NSMenu *)mainMenu; 15 | + (IDEWorkspaceWindowController *)currentWorkspaceWindowController; 16 | + (IDEEditorArea *)currentEditorArea; 17 | + (IDEEditorContext *)currentEditorContext; 18 | + (IDEEditor *)currentEditor; 19 | + (IDESourceCodeEditor *)currentSourceCodeEditor; 20 | + (IDESourceCodeDocument *)currentSourceCodeDocument; 21 | + (DVTSourceTextView *)currentSourceTextView; 22 | + (DVTTextStorage *)currentTextStorage; 23 | + (NSScrollView *)currentScrollView; 24 | 25 | + (NSMenuItem *)getMainMenuItemWithTitle:(NSString *)title; 26 | @end 27 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Julian Weinert 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /JWLinkedLog/pch_file.xctemplate/TemplateInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AllowedTypes 6 | 7 | public.precompiled-c-header 8 | public.precompiled-c-plus-plus-header 9 | 10 | BuildableType 11 | None 12 | DefaultCompletionName 13 | PrefixHeader 14 | Description 15 | A prefix header file that contains LLog. 16 | LLog logs the file name and line where the log happend. In addition, `LLog()` messages are ommitted when building without `DEBUG` variable set, to force messages, use `LLogF()`. 17 | Kind 18 | Xcode.IDEKit.TextSubstitutionFileTemplateKind 19 | MainTemplateFile 20 | ___FILEBASENAME___.pch 21 | SortOrder 22 | 1 23 | Summary 24 | A prefix header file that contains LLog. 25 | 26 | 27 | -------------------------------------------------------------------------------- /JWLinkedLog/DVTDocumentLocation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generated by class-dump 3.3.4 (64 bit). 3 | * 4 | * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2011 by Steve Nygard. 5 | */ 6 | 7 | #import "DVTSimpleSerialization-Protocol.h" 8 | 9 | @class NSNumber, NSString, NSURL; 10 | 11 | @interface DVTDocumentLocation : NSObject 12 | { 13 | NSURL *_documentURL; 14 | NSNumber *_timestamp; 15 | } 16 | 17 | @property(readonly) NSNumber *timestamp; // @synthesize timestamp=_timestamp; 18 | @property(readonly) NSURL *documentURL; // @synthesize documentURL=_documentURL; 19 | //- (void).cxx_destruct; 20 | - (long long)compare:(id)arg1; 21 | - (id)description; 22 | - (void)dvt_writeToSerializer:(id)arg1; 23 | - (id)dvt_initFromDeserializer:(id)arg1; 24 | - (BOOL)isEqualDisregardingTimestamp:(id)arg1; 25 | - (BOOL)isEqualToDocumentLocationDisregardingDocumentURL:(id)arg1; 26 | - (unsigned long long)hash; 27 | - (BOOL)isEqual:(id)arg1; 28 | - (id)copyWithURL:(id)arg1; 29 | - (id)copyWithZone:(struct _NSZone *)arg1; 30 | @property(readonly) NSString *documentURLString; 31 | - (void)encodeWithCoder:(id)arg1; 32 | - (id)initWithCoder:(id)arg1; 33 | - (id)initWithDocumentURL:(id)arg1 timestamp:(id)arg2; 34 | - (id)init; 35 | 36 | @end 37 | 38 | -------------------------------------------------------------------------------- /JWLinkedLog/JWLinkedLog.h: -------------------------------------------------------------------------------- 1 | // 2 | // JWLinkedLog.h 3 | // JWLinkedLog 4 | // 5 | // Created by Julian Weinert on 09.01.15. 6 | // Copyright (c) 2015 Julian Weinert 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | 28 | @interface JWLinkedLog : NSObject 29 | 30 | @property (nonatomic, retain) NSBundle *bundle; 31 | 32 | + (instancetype)sharedPlugin; 33 | 34 | @end -------------------------------------------------------------------------------- /JWLinkedLog/NSTextStorage+findInFiles.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSTextStorage+findInFiles.h 3 | // LinkedLog 4 | // 5 | // Created by Julian Weinert on 09.02.15. 6 | // Copyright (c) 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | 28 | @interface NSTextStorage (findInFiles) 29 | 30 | - (void)_fixAttributesInRange:(NSRange *)range; 31 | - (void)_processEditing; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /LinkedLog.xcodeproj/project.xcworkspace/xcshareddata/LinkedLog.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | F9CB85E7-415A-4E7F-8401-F40218C00A47 9 | IDESourceControlProjectName 10 | LinkedLog 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 98FF8286EC9142A7B4173C5A771CD88A877793B6 14 | https://github.com/julian-weinert/LinkedLog.git 15 | 16 | IDESourceControlProjectPath 17 | LinkedLog.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 98FF8286EC9142A7B4173C5A771CD88A877793B6 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/julian-weinert/LinkedLog.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 98FF8286EC9142A7B4173C5A771CD88A877793B6 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 98FF8286EC9142A7B4173C5A771CD88A877793B6 36 | IDESourceControlWCCName 37 | LinkedLog 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /JWLinkedLog/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | de.julianweinert.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleURLSchemes 27 | 28 | jwlinkedlog 29 | 30 | 31 | 32 | CFBundleVersion 33 | 1 34 | DVTPlugInCompatibilityUUIDs 35 | 36 | C4A681B0-4A26-480E-93EC-1218098B9AA0 37 | AD68E85B-441B-4301-B564-A45E4919A6AD 38 | A16FF353-8441-459E-A50C-B071F53F51B7 39 | 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 40 | 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 41 | 7265231C-39B4-402C-89E1-16167C4CC990 42 | ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C 43 | 44 | LSMinimumSystemVersion 45 | $(MACOSX_DEPLOYMENT_TARGET) 46 | NSPrincipalClass 47 | JWLinkedLog 48 | XC4Compatible 49 | 50 | XCPluginHasUI 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /JWLinkedLog/DVTSourceExpression.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generated by class-dump 3.3.4 (64 bit). 3 | * 4 | * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2011 by Steve Nygard. 5 | */ 6 | 7 | @class DVTTextDocumentLocation, NSDictionary, NSString; 8 | 9 | @interface DVTSourceExpression : NSObject 10 | { 11 | DVTTextDocumentLocation *_location; 12 | DVTTextDocumentLocation *_textSelectionLocation; 13 | NSString *_expressionString; 14 | struct _NSRange _expressionRange; 15 | NSString *_symbolString; 16 | NSString *_textSelectionString; 17 | NSDictionary *_symbolDescription; 18 | id _context; 19 | } 20 | 21 | @property(readonly) id context; // @synthesize context=_context; 22 | @property(readonly) struct _NSRange expressionRange; // @synthesize expressionRange=_expressionRange; 23 | @property(readonly) NSDictionary *symbolDescription; // @synthesize symbolDescription=_symbolDescription; 24 | @property(readonly) DVTTextDocumentLocation *textSelectionLocation; // @synthesize textSelectionLocation=_textSelectionLocation; 25 | @property(readonly) NSString *textSelectionString; // @synthesize textSelectionString=_textSelectionString; 26 | @property(readonly) NSString *symbolString; // @synthesize symbolString=_symbolString; 27 | @property(readonly) NSString *expressionString; // @synthesize expressionString=_expressionString; 28 | @property(readonly) DVTTextDocumentLocation *location; // @synthesize location=_location; 29 | //- (void).cxx_destruct; 30 | - (id)description; 31 | - (id)initWithExpressionString:(id)arg1 symbolString:(id)arg2 location:(id)arg3 symbolDescription:(id)arg4 andContext:(id)arg5; 32 | - (id)initWithExpressionString:(id)arg1 range:(struct _NSRange)arg2 symbolString:(id)arg3 location:(id)arg4 textSelectionString:(id)arg5 textSelectionLocation:(id)arg6 symbolDescription:(id)arg7 andContext:(id)arg8; 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /JWLinkedLog/DVTTextDocumentLocation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generated by class-dump 3.3.4 (64 bit). 3 | * 4 | * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2011 by Steve Nygard. 5 | */ 6 | 7 | #import "DVTDocumentLocation.h" 8 | 9 | @interface DVTTextDocumentLocation : DVTDocumentLocation 10 | { 11 | long long _startingColumnNumber; 12 | long long _endingColumnNumber; 13 | long long _startingLineNumber; 14 | long long _endingLineNumber; 15 | struct _NSRange _characterRange; 16 | } 17 | 18 | @property(readonly) struct _NSRange characterRange; // @synthesize characterRange=_characterRange; 19 | @property(readonly) long long endingLineNumber; // @synthesize endingLineNumber=_endingLineNumber; 20 | @property(readonly) long long startingLineNumber; // @synthesize startingLineNumber=_startingLineNumber; 21 | @property(readonly) long long endingColumnNumber; // @synthesize endingColumnNumber=_endingColumnNumber; 22 | @property(readonly) long long startingColumnNumber; // @synthesize startingColumnNumber=_startingColumnNumber; 23 | - (id)copyWithURL:(id)arg1; 24 | - (long long)compare:(id)arg1; 25 | - (BOOL)isEqualDisregardingTimestamp:(id)arg1; 26 | - (BOOL)isEqualToDocumentLocationDisregardingDocumentURL:(id)arg1; 27 | - (BOOL)isEqual:(id)arg1; 28 | @property(readonly) struct _NSRange lineRange; 29 | - (id)description; 30 | - (void)dvt_writeToSerializer:(id)arg1; 31 | - (id)dvt_initFromDeserializer:(id)arg1; 32 | - (void)encodeWithCoder:(id)arg1; 33 | - (id)initWithCoder:(id)arg1; 34 | - (id)initWithDocumentURL:(id)arg1 timestamp:(id)arg2 characterRange:(struct _NSRange)arg3; 35 | - (id)initWithDocumentURL:(id)arg1 timestamp:(id)arg2 lineRange:(struct _NSRange)arg3; 36 | - (id)initWithDocumentURL:(id)arg1 timestamp:(id)arg2 startingColumnNumber:(long long)arg3 endingColumnNumber:(long long)arg4 startingLineNumber:(long long)arg5 endingLineNumber:(long long)arg6 characterRange:(struct _NSRange)arg7; 37 | 38 | @end 39 | 40 | -------------------------------------------------------------------------------- /JWLinkedLog/DTXcodeUtils/XcodeHeaders/DTXcodeHeaders.h: -------------------------------------------------------------------------------- 1 | 2 | @interface DVTTextStorage : NSTextStorage 3 | /** Whether to syntax highlight the current editor */ 4 | @property(getter=isSyntaxColoringEnabled) BOOL syntaxColoringEnabled; 5 | 6 | /** Converts from a character number in the text to a line number */ 7 | - (NSRange)lineRangeForCharacterRange:(NSRange)characterRange; 8 | 9 | /** Converts from a line number in the text to a character number */ 10 | - (NSRange)characterRangeForLineRange:(NSRange)lineRange; 11 | @end 12 | 13 | @interface DVTCompletingTextView : NSTextView 14 | @end 15 | 16 | @interface DVTSourceTextView : DVTCompletingTextView 17 | @end 18 | 19 | @interface DVTViewController : NSViewController 20 | @end 21 | 22 | @interface IDEViewController : DVTViewController 23 | @end 24 | 25 | @class IDEEditorContext; 26 | @interface IDEEditorArea : IDEViewController 27 | @property(retain, nonatomic) IDEEditorContext *lastActiveEditorContext; 28 | @end 29 | 30 | @interface IDEEditor : IDEViewController 31 | @end 32 | 33 | @interface IDEEditorContext : IDEViewController 34 | @property(retain, nonatomic) IDEEditor *editor; 35 | @property(retain, nonatomic) IDEEditorArea *editorArea; 36 | @end 37 | 38 | @interface IDEEditorDocument : NSDocument 39 | @end 40 | 41 | @interface IDESourceCodeDocument : IDEEditorDocument 42 | @end 43 | 44 | @interface IDESourceCodeEditor : IDEEditor 45 | @property(readonly) IDESourceCodeDocument *sourceCodeDocument; 46 | @property(retain) DVTSourceTextView *textView; 47 | - (id)_jumpToDefinitionOfExpression:(id)arg1 fromScreenPoint:(struct CGPoint)arg2 clickCount:(long long)arg3 modifierFlags:(unsigned long long)arg4; 48 | - (void)jumpToDefinition:(id)arg1; 49 | @end 50 | 51 | @interface IDEComparisonEditor : IDEEditor 52 | @property(retain) IDEEditorDocument *secondaryDocument; 53 | @property(retain) IDEEditorDocument *primaryDocument; 54 | @end 55 | 56 | @interface IDESourceCodeComparisonEditor : IDEComparisonEditor 57 | @property(readonly) DVTSourceTextView *keyTextView; 58 | @end 59 | 60 | @interface IDEWorkspaceWindowController : NSWindowController 61 | @property(readonly) IDEEditorArea *editorArea; 62 | @end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LinkedLog Xcode Plugin 2 | 3 | LinkedLog is a Xcode plugin that includes a Xcode PCH file template that adds the macros `LLog` and `LLogF`. 4 | The `LLog` macro will work like `NSLog` but additionally prints the file name and line number of the call. 5 | 6 | LinkedLog then parses the logs and adds links to the corresponding file and line. 7 | 8 | 9 | ## Status 10 | 11 | [![Stories ToDo](https://badge.waffle.io/julian-weinert/linkedlog.svg?label=todo&title=ToDo)](http://waffle.io/julian-weinert/linkedlog) 12 | [![Stories in Progress](https://badge.waffle.io/julian-weinert/linkedlog.svg?label=progress&title=In%20Progress)](http://waffle.io/julian-weinert/linkedlog) 13 | [![Stories Done](https://badge.waffle.io/julian-weinert/linkedlog.svg?label=done&title=Done)](http://waffle.io/julian-weinert/linkedlog) 14 | 15 | [![Build Status](https://travis-ci.org/julian-weinert/LinkedLog.svg?branch=master)](https://travis-ci.org/julian-weinert/LinkedLog) 16 | [![LinkedLog chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/julian-weinert/LinkedLog?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 17 | 18 | 19 | ## Install 20 | 21 | 1. Build the project to install the plugin. The plugin gets installed in `/Library/Application Support/Developer/Shared/Xcode/Plug-ins/LinkedLog.xcplugin`. 22 | 2. Restart Xcode for the plugin to be activated. 23 | 24 | **Alternatively, install it using [Alcatraz plugin manager](https://github.com/supermarin/Alcatraz).** 25 | 26 | 27 | ## Configuration 28 | 29 | * In Xcode select add files to the project. 30 | * Select the *PCH File+LLog* file template from the *LinkedLog templates* section. 31 | * Navigate to your build settings, search for **prefix** and add the created file to "Prefix header" 32 | * Replace all `NSLog` calls with `LLog` or `LLogF` 33 | 34 | 35 | ## Usage 36 | 37 | Whenever you want a log message, use `LLog(@"string with format: %@", @"'format'");` just as `NSLog`. 38 | The messages will be omitted when building without `DEBUG` build variable. 39 | To force logs to also appear with production build configs use `LLogF` instead. 40 | 41 | 42 | ## Screenshot 43 | 44 | ![LinkedLog](https://raw.githubusercontent.com/julian-weinert/LinkedLog/master/Screenshots/LinkedLog.png) 45 | 46 | 47 | ## Bugs and limitations 48 | 49 | 50 | ### Pull requests 51 | 52 | If you want to contribute, send me a pull request. 53 | 54 | 55 | ### Improvements 56 | 57 | [![Stories ToDo](https://badge.waffle.io/julian-weinert/linkedlog.svg?label=todo&title=ToDo)](http://waffle.io/julian-weinert/linkedlog) 58 | -------------------------------------------------------------------------------- /JWLinkedLog/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // JWLinkedLog 4 | // 5 | // Created by Julian Weinert on 11.01.15. 6 | // Copyright (c) 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #ifndef JTrigger_PrefixHeader_pch 13 | #define JTrigger_PrefixHeader_pch 14 | 15 | // Include any system framework and library headers here that should be included in all compilation units. 16 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 17 | 18 | ////////////////////////////////////////////////////////////////////////////////////// 19 | ////////////////////////////////////////////////////////////////////////////////////// 20 | // // 21 | // LinkedLog, // 22 | // // 23 | // LLog and LLogF // 24 | // // 25 | // are proudly presented by Julian Weinert // 26 | // // 27 | // Created by Julian Weinert on 09.01.15. // 28 | // Copyright (c) 2015 Julian Weinert Softwareentwicklung. All rights reserved. // 29 | // // 30 | // Permission is hereby granted, free of charge, to any person obtaining a copy // 31 | // of this software and associated documentation files (the "Software"), to deal // 32 | // in the Software without restriction, including without limitation the rights // 33 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // 34 | // copies of the Software, and to permit persons to whom the Software is // 35 | // furnished to do so, subject to the following conditions: // 36 | // // 37 | // The above copyright notice and this permission notice shall be included in // 38 | // all copies or substantial portions of the Software. // 39 | // // 40 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // 41 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // 42 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // 43 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // 44 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // 45 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // 46 | // THE SOFTWARE. // 47 | // // 48 | ////////////////////////////////////////////////////////////////////////////////////// 49 | 50 | #ifndef LLog 51 | #define LLogF(format, ...) NSLog(@"%s:%i: %@", __FILE__, __LINE__, [NSString stringWithFormat:format, ##__VA_ARGS__]); 52 | 53 | #ifdef DEBUG 54 | #define LLog(format, ...) LLogF(format, ##__VA_ARGS__); 55 | #else 56 | #define LLog(format, ...) while(0){} 57 | #endif 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /JWLinkedLog/pch_file.xctemplate/___FILEBASENAME___.pch: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #ifndef ___PROJECTNAMEASIDENTIFIER_______FILEBASENAMEASIDENTIFIER_______FILEEXTENSION___ 10 | #define ___PROJECTNAMEASIDENTIFIER_______FILEBASENAMEASIDENTIFIER_______FILEEXTENSION___ 11 | 12 | // Include any system framework and library headers here that should be included in all compilation units. 13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 14 | 15 | ////////////////////////////////////////////////////////////////////////////////////// 16 | ////////////////////////////////////////////////////////////////////////////////////// 17 | // // 18 | // LinkedLog, // 19 | // // 20 | // LLog and LLogF // 21 | // // 22 | // are proudly presented by Julian Weinert // 23 | // // 24 | // Created by Julian Weinert on 09.01.15. // 25 | // Copyright (c) 2015 Julian Weinert Softwareentwicklung. All rights reserved. // 26 | // // 27 | // Permission is hereby granted, free of charge, to any person obtaining a copy // 28 | // of this software and associated documentation files (the "Software"), to deal // 29 | // in the Software without restriction, including without limitation the rights // 30 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // 31 | // copies of the Software, and to permit persons to whom the Software is // 32 | // furnished to do so, subject to the following conditions: // 33 | // // 34 | // The above copyright notice and this permission notice shall be included in // 35 | // all copies or substantial portions of the Software. // 36 | // // 37 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // 38 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // 39 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // 40 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // 41 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // 42 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // 43 | // THE SOFTWARE. // 44 | // // 45 | ////////////////////////////////////////////////////////////////////////////////////// 46 | 47 | #ifndef LLog 48 | #define LLogF(format, ...) NSLog(@"%s:%i: %@", __FILE__, __LINE__, [NSString stringWithFormat:format, ##__VA_ARGS__]); 49 | 50 | #ifdef DEBUG 51 | #define LLog(format, ...) LLogF(format, ##__VA_ARGS__); 52 | #else 53 | #define LLog(format, ...) while(0){} 54 | #endif 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /JWLinkedLog/DTXcodeUtils/Classes/DTXcodeUtils.m: -------------------------------------------------------------------------------- 1 | 2 | #import "DTXcodeUtils.h" 3 | #import "DTXcodeHeaders.h" 4 | 5 | @implementation DTXcodeUtils 6 | 7 | + (NSWindow *)currentWindow { 8 | return [[NSApplication sharedApplication] keyWindow]; 9 | } 10 | 11 | + (NSResponder *)currentWindowResponder { 12 | return [[self currentWindow] firstResponder]; 13 | } 14 | 15 | + (NSMenu *)mainMenu { 16 | return [NSApp mainMenu]; 17 | } 18 | 19 | + (NSMenuItem *)getMainMenuItemWithTitle:(NSString *)title { 20 | return [[self mainMenu] itemWithTitle:title]; 21 | } 22 | 23 | + (IDEWorkspaceWindowController *)currentWorkspaceWindowController { 24 | NSWindowController *result = [self currentWindow].windowController; 25 | if ([result isKindOfClass:NSClassFromString(@"IDEWorkspaceWindowController")]) { 26 | return (IDEWorkspaceWindowController *)result; 27 | } 28 | return nil; 29 | } 30 | 31 | + (IDEEditorArea *)currentEditorArea { 32 | return [self currentWorkspaceWindowController].editorArea; 33 | } 34 | 35 | + (IDEEditorContext *)currentEditorContext { 36 | return [self currentEditorArea].lastActiveEditorContext; 37 | } 38 | 39 | + (IDEEditor *)currentEditor { 40 | return [self currentEditorContext].editor; 41 | } 42 | 43 | + (IDESourceCodeEditor *)currentSourceCodeEditor { 44 | if ([[self currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeEditor")]) { 45 | return (IDESourceCodeEditor *)[self currentEditor]; 46 | } 47 | return nil; 48 | } 49 | 50 | + (IDESourceCodeDocument *)currentSourceCodeDocument { 51 | if ([[self currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeEditor")]) { 52 | return ((IDESourceCodeEditor *)[self currentEditor]).sourceCodeDocument; 53 | } else if ([[self currentEditor] isKindOfClass: 54 | NSClassFromString(@"IDESourceCodeComparisonEditor")]) { 55 | IDEEditorDocument *document = 56 | ((IDESourceCodeComparisonEditor *)[self currentEditor]).primaryDocument; 57 | if ([document isKindOfClass:NSClassFromString(@"IDESourceCodeDocument")]) { 58 | return (IDESourceCodeDocument *)document; 59 | } 60 | } 61 | return nil; 62 | } 63 | 64 | + (DVTSourceTextView *)currentSourceTextView { 65 | if ([[self currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeEditor")]) { 66 | return ((IDESourceCodeEditor *)[self currentEditor]).textView; 67 | } else if ([[self currentEditor] isKindOfClass: 68 | NSClassFromString(@"IDESourceCodeComparisonEditor")]) { 69 | return ((IDESourceCodeComparisonEditor *)[self currentEditor]).keyTextView; 70 | } 71 | return nil; 72 | } 73 | 74 | + (DVTTextStorage *)currentTextStorage { 75 | NSTextView *textView = [self currentSourceTextView]; 76 | if ([textView.textStorage isKindOfClass:NSClassFromString(@"DVTTextStorage")]) { 77 | return (DVTTextStorage *)textView.textStorage; 78 | } 79 | return nil; 80 | } 81 | 82 | + (NSScrollView *)currentScrollView { 83 | NSView *view = [self currentSourceTextView]; 84 | return [view enclosingScrollView]; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /JWLinkedLog/NSTextStorage+findInFiles.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSTextStorage+findInFiles.m 3 | // LinkedLog 4 | // 5 | // Created by Julian Weinert on 09.02.15. 6 | // Copyright (c) 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "NSTextStorage+findInFiles.h" 27 | 28 | @implementation NSTextStorage (findInFiles) 29 | 30 | - (void)_fixAttributesInRange:(NSRange *)range { 31 | [self _fixAttributesInRange:range]; 32 | } 33 | 34 | - (void)_processEditing { 35 | static NSRegularExpression *regExp; 36 | static dispatch_once_t onceToken; 37 | dispatch_once(&onceToken, ^{ 38 | NSString *pattern = @"^[\\d]{4}-[\\d]{2}-[\\d]{2}\\s[\\d]{2}:[\\d]{2}:[\\d]{2}.[\\d]{3}\\s[^\\[]*\\[\\d*:\\d*\\]\\s(.+\\/([^\\/:]+:\\d+)):\\s.*"; 39 | regExp = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionAnchorsMatchLines error:NULL]; 40 | }); 41 | 42 | NSString *consoleText = [self string]; 43 | NSRange paragraphRange = [consoleText paragraphRangeForRange:[self editedRange]]; 44 | 45 | __block NSRange messageRange; 46 | __block NSRange fileNameLineRange; 47 | 48 | NSArray *matches = [regExp matchesInString:consoleText options:NSMatchingReportProgress range:paragraphRange]; 49 | 50 | for (NSTextCheckingResult *result in [matches reverseObjectEnumerator]) { 51 | if ([result numberOfRanges] >= 3) { 52 | messageRange = [result rangeAtIndex:1]; 53 | fileNameLineRange = [result rangeAtIndex:2]; 54 | 55 | if (messageRange.location != NSNotFound && fileNameLineRange.location != NSNotFound 56 | && [consoleText length] >= messageRange.location + messageRange.length 57 | && [consoleText length] >= fileNameLineRange.location + fileNameLineRange.length) { 58 | 59 | NSString *replacement = [consoleText substringWithRange:fileNameLineRange]; 60 | NSString *filePath = [consoleText substringWithRange:messageRange]; 61 | 62 | NSArray *filePathParts = [filePath componentsSeparatedByString:@":"]; 63 | 64 | filePath = [filePathParts firstObject]; 65 | NSString *lineNumber = [filePathParts lastObject]; 66 | 67 | [self replaceCharactersInRange:messageRange withString:replacement]; 68 | messageRange.length = [replacement length]; 69 | 70 | [self addAttribute:NSLinkAttributeName value:@"" range:messageRange]; 71 | [self addAttribute:@"JWLinkedLogLink" value:filePath range:messageRange]; 72 | [self addAttribute:@"JWLinkedLogLine" value:lineNumber range:messageRange]; 73 | } 74 | } 75 | } 76 | 77 | [self _processEditing]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /LinkedLog.xcodeproj/xcshareddata/xcschemes/JWLinkedLog.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 53 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 74 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /JWLinkedLog/JRSwizzle.m: -------------------------------------------------------------------------------- 1 | // JRSwizzle.m semver:1.0 2 | // Copyright (c) 2007-2011 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/MIT 4 | // https://github.com/rentzsch/jrswizzle 5 | 6 | #import "JRSwizzle.h" 7 | 8 | #if TARGET_OS_IPHONE 9 | #import 10 | #import 11 | #else 12 | #import 13 | #endif 14 | 15 | #define SetNSErrorFor(FUNC, ERROR_VAR, FORMAT,...) \ 16 | if (ERROR_VAR) { \ 17 | NSString *errStr = [NSString stringWithFormat:@"%s: " FORMAT,FUNC,##__VA_ARGS__]; \ 18 | *ERROR_VAR = [NSError errorWithDomain:@"NSCocoaErrorDomain" \ 19 | code:-1 \ 20 | userInfo:[NSDictionary dictionaryWithObject:errStr forKey:NSLocalizedDescriptionKey]]; \ 21 | } 22 | #define SetNSError(ERROR_VAR, FORMAT,...) SetNSErrorFor(__func__, ERROR_VAR, FORMAT, ##__VA_ARGS__) 23 | 24 | #if OBJC_API_VERSION >= 2 25 | #define GetClass(obj) object_getClass(obj) 26 | #else 27 | #define GetClass(obj) (obj ? obj->isa : Nil) 28 | #endif 29 | 30 | @implementation NSObject (JRSwizzle) 31 | 32 | + (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_ { 33 | #if OBJC_API_VERSION >= 2 34 | Method origMethod = class_getInstanceMethod(self, origSel_); 35 | if (!origMethod) { 36 | #if TARGET_OS_IPHONE 37 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self class]); 38 | #else 39 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]); 40 | #endif 41 | return NO; 42 | } 43 | 44 | Method altMethod = class_getInstanceMethod(self, altSel_); 45 | if (!altMethod) { 46 | #if TARGET_OS_IPHONE 47 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self class]); 48 | #else 49 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]); 50 | #endif 51 | return NO; 52 | } 53 | 54 | class_addMethod(self, 55 | origSel_, 56 | class_getMethodImplementation(self, origSel_), 57 | method_getTypeEncoding(origMethod)); 58 | class_addMethod(self, 59 | altSel_, 60 | class_getMethodImplementation(self, altSel_), 61 | method_getTypeEncoding(altMethod)); 62 | 63 | method_exchangeImplementations(class_getInstanceMethod(self, origSel_), class_getInstanceMethod(self, altSel_)); 64 | return YES; 65 | #else 66 | // Scan for non-inherited methods. 67 | Method directOriginalMethod = NULL, directAlternateMethod = NULL; 68 | 69 | void *iterator = NULL; 70 | struct objc_method_list *mlist = class_nextMethodList(self, &iterator); 71 | while (mlist) { 72 | int method_index = 0; 73 | for (; method_index < mlist->method_count; method_index++) { 74 | if (mlist->method_list[method_index].method_name == origSel_) { 75 | assert(!directOriginalMethod); 76 | directOriginalMethod = &mlist->method_list[method_index]; 77 | } 78 | if (mlist->method_list[method_index].method_name == altSel_) { 79 | assert(!directAlternateMethod); 80 | directAlternateMethod = &mlist->method_list[method_index]; 81 | } 82 | } 83 | mlist = class_nextMethodList(self, &iterator); 84 | } 85 | 86 | // If either method is inherited, copy it up to the target class to make it non-inherited. 87 | if (!directOriginalMethod || !directAlternateMethod) { 88 | Method inheritedOriginalMethod = NULL, inheritedAlternateMethod = NULL; 89 | if (!directOriginalMethod) { 90 | inheritedOriginalMethod = class_getInstanceMethod(self, origSel_); 91 | if (!inheritedOriginalMethod) { 92 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]); 93 | return NO; 94 | } 95 | } 96 | if (!directAlternateMethod) { 97 | inheritedAlternateMethod = class_getInstanceMethod(self, altSel_); 98 | if (!inheritedAlternateMethod) { 99 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]); 100 | return NO; 101 | } 102 | } 103 | 104 | int hoisted_method_count = !directOriginalMethod && !directAlternateMethod ? 2 : 1; 105 | struct objc_method_list *hoisted_method_list = malloc(sizeof(struct objc_method_list) + (sizeof(struct objc_method)*(hoisted_method_count-1))); 106 | hoisted_method_list->obsolete = NULL; // soothe valgrind - apparently ObjC runtime accesses this value and it shows as uninitialized in valgrind 107 | hoisted_method_list->method_count = hoisted_method_count; 108 | Method hoisted_method = hoisted_method_list->method_list; 109 | 110 | if (!directOriginalMethod) { 111 | bcopy(inheritedOriginalMethod, hoisted_method, sizeof(struct objc_method)); 112 | directOriginalMethod = hoisted_method++; 113 | } 114 | if (!directAlternateMethod) { 115 | bcopy(inheritedAlternateMethod, hoisted_method, sizeof(struct objc_method)); 116 | directAlternateMethod = hoisted_method; 117 | } 118 | class_addMethods(self, hoisted_method_list); 119 | } 120 | 121 | // Swizzle. 122 | IMP temp = directOriginalMethod->method_imp; 123 | directOriginalMethod->method_imp = directAlternateMethod->method_imp; 124 | directAlternateMethod->method_imp = temp; 125 | 126 | return YES; 127 | #endif 128 | } 129 | 130 | + (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_ { 131 | return [GetClass((id)self) jr_swizzleMethod:origSel_ withMethod:altSel_ error:error_]; 132 | } 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /JWLinkedLog/JWLinkedLog.m: -------------------------------------------------------------------------------- 1 | // 2 | // JWLinkedLog.m 3 | // JWLinkedLog 4 | // 5 | // Created by Julian Weinert on 09.01.15. 6 | // Copyright (c) 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "JWLinkedLog.h" 27 | #import "JRSwizzle.h" 28 | #import "NSTextStorage+findInFiles.h" 29 | 30 | #import "DVTSourceExpression.h" 31 | #import "DVTTextDocumentLocation.h" 32 | 33 | #import "DTXcodeUtils.h" 34 | #import "DTXcodeHeaders.h" 35 | 36 | #import 37 | 38 | @implementation NSTextView (mouseDown) 39 | - (void)_mouseDown:(NSEvent *)theEvent { 40 | NSPoint clickPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; 41 | NSInteger charIndex = [self characterIndexForInsertionAtPoint:clickPoint]; 42 | NSRange rangePointer; 43 | 44 | if ((![self isKindOfClass:NSClassFromString(@"IDEConsoleTextView")]) || ([[self attributedString] length] < 1) || (charIndex > [[self attributedString] length] - 1)) { 45 | [self _mouseDown:theEvent]; 46 | return; 47 | } 48 | 49 | NSDictionary *attributes = [[self attributedString] attributesAtIndex:charIndex effectiveRange:&rangePointer]; 50 | 51 | if (![attributes objectForKey:@"JWLinkedLogLink"] || ![attributes objectForKey:@"JWLinkedLogLine"]) { 52 | [self _mouseDown:theEvent]; 53 | return; 54 | } 55 | 56 | NSString *filePath = [attributes objectForKey:@"JWLinkedLogLink"]; 57 | NSUInteger lineNumber = [[attributes objectForKey:@"JWLinkedLogLine"] integerValue] - 1; 58 | 59 | IDEWorkspaceWindowController *workspaceController = [DTXcodeUtils currentWorkspaceWindowController]; 60 | 61 | if (workspaceController) { 62 | if ([(id)[NSApp delegate] application:NSApp openFile:filePath]) { 63 | IDESourceCodeEditor *editor = [DTXcodeUtils currentSourceCodeEditor]; 64 | 65 | if (editor) { 66 | NSTextView *textView = [editor textView]; 67 | 68 | if (textView) { 69 | NSString *sourceCode = [textView string]; 70 | 71 | NSArray *results = [[NSRegularExpression regularExpressionWithPattern:@"\n" options:0 error:nil] matchesInString:sourceCode options:NSMatchingReportCompletion range:NSMakeRange(0, [sourceCode length])]; 72 | 73 | if ([results count] <= lineNumber) { 74 | return; 75 | } 76 | 77 | NSTextCheckingResult *checkingResult = [results objectAtIndex:lineNumber]; 78 | NSUInteger location = checkingResult.range.location; 79 | 80 | NSRange lineRange = [sourceCode lineRangeForRange:NSMakeRange(location, 0)]; 81 | 82 | [textView scrollRangeToVisible:lineRange]; 83 | [textView setSelectedRange:lineRange]; 84 | } 85 | } 86 | } 87 | } 88 | } 89 | @end 90 | 91 | static JWLinkedLog *sharedPlugin; 92 | 93 | @implementation JWLinkedLog 94 | 95 | + (void)pluginDidLoad:(NSBundle *)plugin { 96 | static dispatch_once_t onceToken; 97 | NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"]; 98 | if ([currentApplicationName isEqual:@"Xcode"]) { 99 | dispatch_once(&onceToken, ^{ 100 | 101 | sharedPlugin = [[self alloc] initWithBundle:plugin]; 102 | 103 | SEL orgSelector = @selector(fixAttributesInRange:); 104 | SEL newSelector = @selector(_fixAttributesInRange:); 105 | 106 | NSError *swizzlingError; 107 | 108 | if (![NSTextStorage jr_swizzleMethod:orgSelector withMethod:newSelector error:&swizzlingError]) { 109 | NSLog(@"swizzling error: %@", swizzlingError); 110 | } 111 | 112 | orgSelector = @selector(processEditing); 113 | newSelector = @selector(_processEditing); 114 | 115 | swizzlingError = nil; 116 | 117 | if (![NSTextStorage jr_swizzleMethod:orgSelector withMethod:newSelector error:&swizzlingError]) { 118 | NSLog(@"swizzling error: %@", swizzlingError); 119 | } 120 | 121 | orgSelector = @selector(mouseDown:); 122 | newSelector = @selector(_mouseDown:); 123 | 124 | swizzlingError = nil; 125 | 126 | if (![NSTextView jr_swizzleMethod:orgSelector withMethod:newSelector error:&swizzlingError]) { 127 | NSLog(@"swizzling error: %@", swizzlingError); 128 | } 129 | }); 130 | } 131 | } 132 | 133 | + (instancetype)sharedPlugin { 134 | return sharedPlugin; 135 | } 136 | 137 | - (id)initWithBundle:(NSBundle *)plugin { 138 | if (self = [super init]) { 139 | // reference to plugin's bundle, for resource access 140 | self.bundle = plugin; 141 | } 142 | 143 | return self; 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /LinkedLog.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CB1684561A8932AB002F3D2F /* JRSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = CB1684531A8932AB002F3D2F /* JRSwizzle.m */; }; 11 | CB1684571A8932AB002F3D2F /* NSTextStorage+findInFiles.m in Sources */ = {isa = PBXBuildFile; fileRef = CB1684551A8932AB002F3D2F /* NSTextStorage+findInFiles.m */; }; 12 | CB34A6CD1A916C66008B586A /* TemplateIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CB34A6CA1A916C66008B586A /* TemplateIcon.png */; }; 13 | CB34A6CE1A916C66008B586A /* TemplateIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB34A6CB1A916C66008B586A /* TemplateIcon@2x.png */; }; 14 | CB34A6CF1A916C66008B586A /* TemplateInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = CB34A6CC1A916C66008B586A /* TemplateInfo.plist */; }; 15 | CB4C0ADA1A896281004CCD56 /* DTXcodeUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CB4C0AD71A896281004CCD56 /* DTXcodeUtils.m */; }; 16 | CB95CB411A600FE000E4AE6D /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB95CB401A600FE000E4AE6D /* AppKit.framework */; }; 17 | CB95CB431A600FE000E4AE6D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB95CB421A600FE000E4AE6D /* Foundation.framework */; }; 18 | CB95CB4B1A600FE000E4AE6D /* JWLinkedLog.m in Sources */ = {isa = PBXBuildFile; fileRef = CB95CB4A1A600FE000E4AE6D /* JWLinkedLog.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | CB1684521A8932AB002F3D2F /* JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JRSwizzle.h; sourceTree = ""; }; 23 | CB1684531A8932AB002F3D2F /* JRSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JRSwizzle.m; sourceTree = ""; }; 24 | CB1684541A8932AB002F3D2F /* NSTextStorage+findInFiles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTextStorage+findInFiles.h"; sourceTree = ""; }; 25 | CB1684551A8932AB002F3D2F /* NSTextStorage+findInFiles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTextStorage+findInFiles.m"; sourceTree = ""; }; 26 | CB16845C1A894811002F3D2F /* DVTSourceExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DVTSourceExpression.h; sourceTree = ""; }; 27 | CB34A6C91A916C66008B586A /* ___FILEBASENAME___.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "___FILEBASENAME___.pch"; sourceTree = ""; }; 28 | CB34A6CA1A916C66008B586A /* TemplateIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = TemplateIcon.png; sourceTree = ""; }; 29 | CB34A6CB1A916C66008B586A /* TemplateIcon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "TemplateIcon@2x.png"; sourceTree = ""; }; 30 | CB34A6CC1A916C66008B586A /* TemplateInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = TemplateInfo.plist; sourceTree = ""; }; 31 | CB4C0AD11A895E9E004CCD56 /* DVTTextDocumentLocation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DVTTextDocumentLocation.h; sourceTree = ""; }; 32 | CB4C0AD21A895EF2004CCD56 /* DVTDocumentLocation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DVTDocumentLocation.h; sourceTree = ""; }; 33 | CB4C0AD31A895F48004CCD56 /* DVTSimpleSerialization-Protocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DVTSimpleSerialization-Protocol.h"; sourceTree = ""; }; 34 | CB4C0AD61A896281004CCD56 /* DTXcodeUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTXcodeUtils.h; sourceTree = ""; }; 35 | CB4C0AD71A896281004CCD56 /* DTXcodeUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTXcodeUtils.m; sourceTree = ""; }; 36 | CB4C0AD91A896281004CCD56 /* DTXcodeHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTXcodeHeaders.h; sourceTree = ""; }; 37 | CB95CB3D1A600FE000E4AE6D /* LinkedLog.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LinkedLog.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | CB95CB401A600FE000E4AE6D /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 39 | CB95CB421A600FE000E4AE6D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 40 | CB95CB461A600FE000E4AE6D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | CB95CB491A600FE000E4AE6D /* JWLinkedLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JWLinkedLog.h; sourceTree = ""; }; 42 | CB95CB4A1A600FE000E4AE6D /* JWLinkedLog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JWLinkedLog.m; sourceTree = ""; }; 43 | CBEE7ECC1A61F1C3003DD744 /* PrefixHeader.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | CB95CB3B1A600FE000E4AE6D /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | CB95CB411A600FE000E4AE6D /* AppKit.framework in Frameworks */, 52 | CB95CB431A600FE000E4AE6D /* Foundation.framework in Frameworks */, 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXFrameworksBuildPhase section */ 57 | 58 | /* Begin PBXGroup section */ 59 | CB34A6C81A916C66008B586A /* pch_file.xctemplate */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | CB34A6C91A916C66008B586A /* ___FILEBASENAME___.pch */, 63 | CB34A6CA1A916C66008B586A /* TemplateIcon.png */, 64 | CB34A6CB1A916C66008B586A /* TemplateIcon@2x.png */, 65 | CB34A6CC1A916C66008B586A /* TemplateInfo.plist */, 66 | ); 67 | path = pch_file.xctemplate; 68 | sourceTree = ""; 69 | }; 70 | CB4C0AD41A896281004CCD56 /* DTXcodeUtils */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | CB4C0AD51A896281004CCD56 /* Classes */, 74 | CB4C0AD81A896281004CCD56 /* XcodeHeaders */, 75 | ); 76 | path = DTXcodeUtils; 77 | sourceTree = ""; 78 | }; 79 | CB4C0AD51A896281004CCD56 /* Classes */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | CB4C0AD61A896281004CCD56 /* DTXcodeUtils.h */, 83 | CB4C0AD71A896281004CCD56 /* DTXcodeUtils.m */, 84 | ); 85 | path = Classes; 86 | sourceTree = ""; 87 | }; 88 | CB4C0AD81A896281004CCD56 /* XcodeHeaders */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | CB4C0AD91A896281004CCD56 /* DTXcodeHeaders.h */, 92 | ); 93 | path = XcodeHeaders; 94 | sourceTree = ""; 95 | }; 96 | CB95CB341A600FE000E4AE6D = { 97 | isa = PBXGroup; 98 | children = ( 99 | CB95CB441A600FE000E4AE6D /* JWLinkedLog */, 100 | CB95CB3F1A600FE000E4AE6D /* Frameworks */, 101 | CB95CB3E1A600FE000E4AE6D /* Products */, 102 | ); 103 | sourceTree = ""; 104 | }; 105 | CB95CB3E1A600FE000E4AE6D /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | CB95CB3D1A600FE000E4AE6D /* LinkedLog.xcplugin */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | CB95CB3F1A600FE000E4AE6D /* Frameworks */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | CB95CB401A600FE000E4AE6D /* AppKit.framework */, 117 | CB95CB421A600FE000E4AE6D /* Foundation.framework */, 118 | ); 119 | name = Frameworks; 120 | sourceTree = ""; 121 | }; 122 | CB95CB441A600FE000E4AE6D /* JWLinkedLog */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | CB95CB491A600FE000E4AE6D /* JWLinkedLog.h */, 126 | CB95CB4A1A600FE000E4AE6D /* JWLinkedLog.m */, 127 | CB1684521A8932AB002F3D2F /* JRSwizzle.h */, 128 | CB1684531A8932AB002F3D2F /* JRSwizzle.m */, 129 | CB16845C1A894811002F3D2F /* DVTSourceExpression.h */, 130 | CB4C0AD21A895EF2004CCD56 /* DVTDocumentLocation.h */, 131 | CB4C0AD11A895E9E004CCD56 /* DVTTextDocumentLocation.h */, 132 | CB4C0AD31A895F48004CCD56 /* DVTSimpleSerialization-Protocol.h */, 133 | CB1684541A8932AB002F3D2F /* NSTextStorage+findInFiles.h */, 134 | CB1684551A8932AB002F3D2F /* NSTextStorage+findInFiles.m */, 135 | CB4C0AD41A896281004CCD56 /* DTXcodeUtils */, 136 | CB95CB451A600FE000E4AE6D /* Supporting Files */, 137 | ); 138 | path = JWLinkedLog; 139 | sourceTree = ""; 140 | }; 141 | CB95CB451A600FE000E4AE6D /* Supporting Files */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | CB34A6C81A916C66008B586A /* pch_file.xctemplate */, 145 | CBEE7ECC1A61F1C3003DD744 /* PrefixHeader.pch */, 146 | CB95CB461A600FE000E4AE6D /* Info.plist */, 147 | ); 148 | name = "Supporting Files"; 149 | sourceTree = ""; 150 | }; 151 | /* End PBXGroup section */ 152 | 153 | /* Begin PBXNativeTarget section */ 154 | CB95CB3C1A600FE000E4AE6D /* LinkedLog */ = { 155 | isa = PBXNativeTarget; 156 | buildConfigurationList = CB95CB4E1A600FE000E4AE6D /* Build configuration list for PBXNativeTarget "LinkedLog" */; 157 | buildPhases = ( 158 | CB95CB391A600FE000E4AE6D /* Sources */, 159 | CB95CB3A1A600FE000E4AE6D /* Resources */, 160 | CB95CB3B1A600FE000E4AE6D /* Frameworks */, 161 | CB34A6D11A916D34008B586A /* Install PCH File Template */, 162 | ); 163 | buildRules = ( 164 | ); 165 | dependencies = ( 166 | ); 167 | name = LinkedLog; 168 | productName = JWLinkedLog; 169 | productReference = CB95CB3D1A600FE000E4AE6D /* LinkedLog.xcplugin */; 170 | productType = "com.apple.product-type.bundle"; 171 | }; 172 | /* End PBXNativeTarget section */ 173 | 174 | /* Begin PBXProject section */ 175 | CB95CB351A600FE000E4AE6D /* Project object */ = { 176 | isa = PBXProject; 177 | attributes = { 178 | LastUpgradeCheck = 0610; 179 | ORGANIZATIONNAME = "Julian Weinert Softwareentwicklung"; 180 | TargetAttributes = { 181 | CB95CB3C1A600FE000E4AE6D = { 182 | CreatedOnToolsVersion = 6.1.1; 183 | }; 184 | }; 185 | }; 186 | buildConfigurationList = CB95CB381A600FE000E4AE6D /* Build configuration list for PBXProject "LinkedLog" */; 187 | compatibilityVersion = "Xcode 3.2"; 188 | developmentRegion = English; 189 | hasScannedForEncodings = 0; 190 | knownRegions = ( 191 | en, 192 | ); 193 | mainGroup = CB95CB341A600FE000E4AE6D; 194 | productRefGroup = CB95CB3E1A600FE000E4AE6D /* Products */; 195 | projectDirPath = ""; 196 | projectRoot = ""; 197 | targets = ( 198 | CB95CB3C1A600FE000E4AE6D /* LinkedLog */, 199 | ); 200 | }; 201 | /* End PBXProject section */ 202 | 203 | /* Begin PBXResourcesBuildPhase section */ 204 | CB95CB3A1A600FE000E4AE6D /* Resources */ = { 205 | isa = PBXResourcesBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | CB34A6CF1A916C66008B586A /* TemplateInfo.plist in Resources */, 209 | CB34A6CD1A916C66008B586A /* TemplateIcon.png in Resources */, 210 | CB34A6CE1A916C66008B586A /* TemplateIcon@2x.png in Resources */, 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | /* End PBXResourcesBuildPhase section */ 215 | 216 | /* Begin PBXShellScriptBuildPhase section */ 217 | CB34A6D11A916D34008B586A /* Install PCH File Template */ = { 218 | isa = PBXShellScriptBuildPhase; 219 | buildActionMask = 12; 220 | files = ( 221 | ); 222 | inputPaths = ( 223 | ); 224 | name = "Install PCH File Template"; 225 | outputPaths = ( 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | shellPath = /bin/sh; 229 | shellScript = "target_path=\"$HOME/Library/Developer/Xcode/Templates/File Templates/LinkedLog Templates\"\nsource_path=\"$SRCROOT/JWLinkedLog/pch_file.xctemplate\"\n\ntest -d \"$target_path\" || mkdir -p \"$target_path\"\ntest -d \"$target_path/PCH File+LLog.xctemplate/\" && rm -r \"$target_path/PCH File+LLog.xctemplate/\"\ncp -rf \"$source_path\" \"$target_path/PCH File+LLog.xctemplate\"\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; 230 | }; 231 | /* End PBXShellScriptBuildPhase section */ 232 | 233 | /* Begin PBXSourcesBuildPhase section */ 234 | CB95CB391A600FE000E4AE6D /* Sources */ = { 235 | isa = PBXSourcesBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | CB1684561A8932AB002F3D2F /* JRSwizzle.m in Sources */, 239 | CB4C0ADA1A896281004CCD56 /* DTXcodeUtils.m in Sources */, 240 | CB95CB4B1A600FE000E4AE6D /* JWLinkedLog.m in Sources */, 241 | CB1684571A8932AB002F3D2F /* NSTextStorage+findInFiles.m in Sources */, 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | }; 245 | /* End PBXSourcesBuildPhase section */ 246 | 247 | /* Begin XCBuildConfiguration section */ 248 | CB95CB4C1A600FE000E4AE6D /* Debug */ = { 249 | isa = XCBuildConfiguration; 250 | buildSettings = { 251 | ALWAYS_SEARCH_USER_PATHS = NO; 252 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 253 | CLANG_CXX_LIBRARY = "libc++"; 254 | CLANG_ENABLE_MODULES = YES; 255 | CLANG_ENABLE_OBJC_ARC = YES; 256 | CLANG_WARN_BOOL_CONVERSION = YES; 257 | CLANG_WARN_CONSTANT_CONVERSION = YES; 258 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 259 | CLANG_WARN_EMPTY_BODY = YES; 260 | CLANG_WARN_ENUM_CONVERSION = YES; 261 | CLANG_WARN_INT_CONVERSION = YES; 262 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 263 | CLANG_WARN_UNREACHABLE_CODE = YES; 264 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 265 | COPY_PHASE_STRIP = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_DYNAMIC_NO_PIC = NO; 269 | GCC_OPTIMIZATION_LEVEL = 0; 270 | GCC_PREPROCESSOR_DEFINITIONS = ( 271 | "DEBUG=1", 272 | "$(inherited)", 273 | ); 274 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 275 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 276 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 277 | GCC_WARN_UNDECLARED_SELECTOR = YES; 278 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 279 | GCC_WARN_UNUSED_FUNCTION = YES; 280 | GCC_WARN_UNUSED_VARIABLE = YES; 281 | MTL_ENABLE_DEBUG_INFO = YES; 282 | ONLY_ACTIVE_ARCH = YES; 283 | }; 284 | name = Debug; 285 | }; 286 | CB95CB4D1A600FE000E4AE6D /* Release */ = { 287 | isa = XCBuildConfiguration; 288 | buildSettings = { 289 | ALWAYS_SEARCH_USER_PATHS = NO; 290 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 291 | CLANG_CXX_LIBRARY = "libc++"; 292 | CLANG_ENABLE_MODULES = YES; 293 | CLANG_ENABLE_OBJC_ARC = YES; 294 | CLANG_WARN_BOOL_CONVERSION = YES; 295 | CLANG_WARN_CONSTANT_CONVERSION = YES; 296 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 297 | CLANG_WARN_EMPTY_BODY = YES; 298 | CLANG_WARN_ENUM_CONVERSION = YES; 299 | CLANG_WARN_INT_CONVERSION = YES; 300 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 301 | CLANG_WARN_UNREACHABLE_CODE = YES; 302 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 303 | COPY_PHASE_STRIP = YES; 304 | ENABLE_NS_ASSERTIONS = NO; 305 | ENABLE_STRICT_OBJC_MSGSEND = YES; 306 | GCC_C_LANGUAGE_STANDARD = gnu99; 307 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 308 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 309 | GCC_WARN_UNDECLARED_SELECTOR = YES; 310 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 311 | GCC_WARN_UNUSED_FUNCTION = YES; 312 | GCC_WARN_UNUSED_VARIABLE = YES; 313 | MTL_ENABLE_DEBUG_INFO = NO; 314 | }; 315 | name = Release; 316 | }; 317 | CB95CB4F1A600FE000E4AE6D /* Debug */ = { 318 | isa = XCBuildConfiguration; 319 | buildSettings = { 320 | COMBINE_HIDPI_IMAGES = YES; 321 | DEPLOYMENT_LOCATION = YES; 322 | DSTROOT = "$(HOME)"; 323 | GCC_PREFIX_HEADER = JWLinkedLog/PrefixHeader.pch; 324 | INFOPLIST_FILE = JWLinkedLog/Info.plist; 325 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 326 | MACOSX_DEPLOYMENT_TARGET = 10.10; 327 | PRODUCT_NAME = LinkedLog; 328 | WRAPPER_EXTENSION = xcplugin; 329 | }; 330 | name = Debug; 331 | }; 332 | CB95CB501A600FE000E4AE6D /* Release */ = { 333 | isa = XCBuildConfiguration; 334 | buildSettings = { 335 | COMBINE_HIDPI_IMAGES = YES; 336 | DEPLOYMENT_LOCATION = YES; 337 | DSTROOT = "$(HOME)"; 338 | GCC_PREFIX_HEADER = JWLinkedLog/PrefixHeader.pch; 339 | INFOPLIST_FILE = JWLinkedLog/Info.plist; 340 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 341 | MACOSX_DEPLOYMENT_TARGET = 10.10; 342 | PRODUCT_NAME = LinkedLog; 343 | WRAPPER_EXTENSION = xcplugin; 344 | }; 345 | name = Release; 346 | }; 347 | /* End XCBuildConfiguration section */ 348 | 349 | /* Begin XCConfigurationList section */ 350 | CB95CB381A600FE000E4AE6D /* Build configuration list for PBXProject "LinkedLog" */ = { 351 | isa = XCConfigurationList; 352 | buildConfigurations = ( 353 | CB95CB4C1A600FE000E4AE6D /* Debug */, 354 | CB95CB4D1A600FE000E4AE6D /* Release */, 355 | ); 356 | defaultConfigurationIsVisible = 0; 357 | defaultConfigurationName = Release; 358 | }; 359 | CB95CB4E1A600FE000E4AE6D /* Build configuration list for PBXNativeTarget "LinkedLog" */ = { 360 | isa = XCConfigurationList; 361 | buildConfigurations = ( 362 | CB95CB4F1A600FE000E4AE6D /* Debug */, 363 | CB95CB501A600FE000E4AE6D /* Release */, 364 | ); 365 | defaultConfigurationIsVisible = 0; 366 | defaultConfigurationName = Release; 367 | }; 368 | /* End XCConfigurationList section */ 369 | }; 370 | rootObject = CB95CB351A600FE000E4AE6D /* Project object */; 371 | } 372 | --------------------------------------------------------------------------------