├── Installer ├── .DS_Store ├── scripts │ ├── preflight │ └── postflight ├── resources │ └── en.lproj │ │ ├── background.tiff │ │ ├── Welcome.rtf │ │ └── ReadMe.rtf ├── Info.plist └── build_installer_pkg.command ├── Resources ├── .DS_Store ├── ATROX.TTF ├── English.lproj │ └── InfoPlist.strings ├── Footer.png ├── Header.png ├── memlak.png ├── DarkCell.png ├── LightCell.png ├── CodePilotIcon.icns ├── CodePilotPrefs.png ├── HeaderWithInfo.png ├── MacoscopeLogo.png ├── ResultSelection.png ├── InfoLabelBarRect.png ├── NewCodePilotIcon.png ├── InfoLabelBarTriangle.png ├── UpperStatusBackground.png └── Info.plist ├── Screenshots ├── CodePilot_01.png └── CodePilot_02.png ├── CodePilot.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── CodePilot.xccheckout └── xcshareddata │ └── xcschemes │ └── CodePilot.xcscheme ├── Classes ├── NSURL+Xcode.h ├── CPResultScrollView.h ├── NSURL+Anchors.h ├── main.m ├── CPFirstRunWindowView.h ├── CPNoProjectOpenWindowView.h ├── CPStatusLabel.h ├── NSView+AllSubviews.h ├── NSWorkspace+OpenFileOnLine.h ├── CPXcodeVersionUnsupportedWindowView.h ├── NSColor+ColorArithmetic.h ├── NSAttributedString+Hyperlink.h ├── NSView+RoundedFrame.h ├── CPSearchFieldTextView.h ├── NSAppleEventDescriptor+ToObject.h ├── NSURL+Anchors.m ├── CPHUDViewWithRoundCorners.h ├── NSString+Abbreviation.h ├── CPResult.h ├── NSArray+MiscExtensions.h ├── CPSymbolCache.h ├── NSMutableArray+MiscExtensions.h ├── CPResultTableViewColumn.h ├── CPPreferencesViewController.h ├── CPResultTableView.h ├── CPPreferencesView.h ├── CPFirstRunWindowView.m ├── NSNumber+VersionComparison.h ├── CPWorkspaceSymbolCache.h ├── CPNoProjectOpenWindowView.m ├── CPInfoWindowView.h ├── NSString+MiscExtensions.h ├── CPFileReferenceCell.h ├── NSURL+Xcode.m ├── CPHUDViewWithRoundCorners.m ├── CPWorkspaceSymbolCache.m ├── CPPreferencesToolbarDelegate.h ├── CPSymbolCell.h ├── CPXcodeVersionUnsupportedWindowView.m ├── CPResultScrollView.m ├── CPResultCell.h ├── CPCodePilotWindowDelegate.h ├── CPXcodeInterfaces.m ├── CPWindow.h ├── CPStatusLabel.m ├── AMIndeterminateProgressIndicatorCell.h ├── NSView+AllSubviews.m ├── CPPreferencesViewController.m ├── CPSearchField.h ├── NSAttributedString+Hyperlink.m ├── CPResult.m ├── CPCodePilotPlugin.h ├── NSArray+MiscExtensions.m ├── NSNumber+VersionComparison.m ├── CPFileReference.h ├── CPSymbol.h ├── NSColor+ColorArithmetic.m ├── CPSelectedObjectCell.h ├── NSMutableArray+MiscExtensions.m ├── NSString+MiscExtensions.m ├── CPPluginInstaller.h ├── MCStringScoring.h ├── NSView+RoundedFrame.m ├── QSBSmallScroller.h ├── NSWorkspace+OpenFileOnLine.m ├── CPResultTableViewColumn.m ├── CPResultTableView.m ├── CPInfoWindowView.m ├── CPSymbolCache.m ├── CPSearchWindowView.h ├── CPSelectedObjectCell.m ├── CPSearchController.h ├── CPCodePilotWindowDelegate.m ├── CPCodePilotPlugin.m ├── CPXcodeWrapper.h ├── QSBSmallScroller.m ├── NSString+Abbreviation.m ├── CPSearchFieldTextView.m ├── NSAppleEventDescriptor+ToObject.m ├── CPWindow.m ├── CPResultCell.m ├── CPFileReferenceCell.m ├── CPFileReference.m ├── AMIndeterminateProgressIndicatorCell.m ├── CPSymbolCell.m ├── CPSymbol.m ├── CPPreferencesView.m ├── CPSearchField.m ├── CPPluginInstaller.m ├── CPPreferencesToolbarDelegate.m └── CPCodePilotConfig.h ├── Other Sources └── CodePilot_Prefix.pch ├── MCCommons ├── MCCommons.h ├── MCStringScoring.h ├── MCLog.h └── MCLog.m ├── scripts └── replace_plugin.sh ├── README.md └── .gitignore /Installer/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Installer/.DS_Store -------------------------------------------------------------------------------- /Resources/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/.DS_Store -------------------------------------------------------------------------------- /Resources/ATROX.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/ATROX.TTF -------------------------------------------------------------------------------- /Resources/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Resources/Footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/Footer.png -------------------------------------------------------------------------------- /Resources/Header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/Header.png -------------------------------------------------------------------------------- /Resources/memlak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/memlak.png -------------------------------------------------------------------------------- /Resources/DarkCell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/DarkCell.png -------------------------------------------------------------------------------- /Resources/LightCell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/LightCell.png -------------------------------------------------------------------------------- /Installer/scripts/preflight: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | pkgutil --forget net.macoscope.CodePilot3.pkg 4 | 5 | exit 0 6 | -------------------------------------------------------------------------------- /Resources/CodePilotIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/CodePilotIcon.icns -------------------------------------------------------------------------------- /Resources/CodePilotPrefs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/CodePilotPrefs.png -------------------------------------------------------------------------------- /Resources/HeaderWithInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/HeaderWithInfo.png -------------------------------------------------------------------------------- /Resources/MacoscopeLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/MacoscopeLogo.png -------------------------------------------------------------------------------- /Resources/ResultSelection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/ResultSelection.png -------------------------------------------------------------------------------- /Screenshots/CodePilot_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Screenshots/CodePilot_01.png -------------------------------------------------------------------------------- /Screenshots/CodePilot_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Screenshots/CodePilot_02.png -------------------------------------------------------------------------------- /Resources/InfoLabelBarRect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/InfoLabelBarRect.png -------------------------------------------------------------------------------- /Resources/NewCodePilotIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/NewCodePilotIcon.png -------------------------------------------------------------------------------- /Resources/InfoLabelBarTriangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/InfoLabelBarTriangle.png -------------------------------------------------------------------------------- /Resources/UpperStatusBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Resources/UpperStatusBackground.png -------------------------------------------------------------------------------- /Installer/resources/en.lproj/background.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macoscope/CodePilot/HEAD/Installer/resources/en.lproj/background.tiff -------------------------------------------------------------------------------- /CodePilot.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Classes/NSURL+Xcode.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+Xcode.h 3 | // CodePilot 4 | // 5 | // Created by Fjölnir Ásgeirsson on 2/2/14. 6 | // Copyright (c) 2014 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSURL (Xcode) 12 | - (BOOL)cp_opensInXcode; 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/CPResultScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPResultScrollView.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 5/26/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface CPResultScrollView : NSScrollView 13 | @end 14 | -------------------------------------------------------------------------------- /Other Sources/CodePilot_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'CodePilot' target in the 'CodePilot' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | # import 7 | # import 8 | # import "CPCodePilotConfig.h" 9 | # import "CPXcodeInterfaces.h" 10 | #endif 11 | -------------------------------------------------------------------------------- /Classes/NSURL+Anchors.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+Anchors.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 6/20/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSURL (Anchors) 12 | - (NSString *)pathWithoutAnchor; 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // XcodeToolbox 4 | // 5 | // Created by Zbigniew Sobiecki on 2/9/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /Classes/CPFirstRunWindowView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPFirstRunWindowView.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/21/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPInfoWindowView.h" 11 | 12 | @interface CPFirstRunWindowView : CPInfoWindowView 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/CPNoProjectOpenWindowView.h: -------------------------------------------------------------------------------- 1 | // 2 | // NoProjectOpenWindowView.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/19/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPInfoWindowView.h" 11 | 12 | @interface CPNoProjectOpenWindowView : CPInfoWindowView 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/CPStatusLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // StatusLabel.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/20/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CPStatusLabel : NSTextField 12 | @property (nonatomic, strong) NSURL *clickUrl; 13 | 14 | - (CGFloat)textWidth; 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/NSView+AllSubviews.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+AllSubviews.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/23/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSView (AllSubviews) 12 | - (NSArray *)allSubviews; 13 | - (NSArray *)allSubviewsOfClass:(Class)klass; 14 | @end 15 | -------------------------------------------------------------------------------- /Classes/NSWorkspace+OpenFileOnLine.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSWorkspace+OpenFileOnLine.h 3 | // CodePilot 4 | // 5 | // Created by Fjölnir Ásgeirsson on 2/2/14. 6 | // Copyright (c) 2014 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSWorkspace (OpenFileOnLine) 12 | - (void)cp_openURL:(NSURL *)url onLine:(NSUInteger)line; 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/CPXcodeVersionUnsupportedWindowView.h: -------------------------------------------------------------------------------- 1 | // 2 | // XcodeVersionUnsupportedWindowView.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/19/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPInfoWindowView.h" 11 | 12 | @interface CPXcodeVersionUnsupportedWindowView : CPInfoWindowView 13 | @end 14 | -------------------------------------------------------------------------------- /Installer/scripts/postflight: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PLUGINS_DIR="$HOME/Library/Application Support/Developer/Shared/Xcode/Plug-ins" 4 | 5 | if [ ! -d "$PLUGINS_DIR" ] 6 | then 7 | mkdir -p "$PLUGINS_DIR" 8 | fi 9 | 10 | rm -rf "$PLUGINS_DIR/CodePilot3.xcplugin" 11 | mv /tmp/CodePilot3.xcplugin "$PLUGINS_DIR" 12 | 13 | pkgutil --forget net.macoscope.CodePilot3.pkg 14 | 15 | exit 0 16 | -------------------------------------------------------------------------------- /Classes/NSColor+ColorArithmetic.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+ColorArithmetic.h 3 | // CodePilot 4 | // 5 | // Created by Karol Kozub on 08.08.2013. 6 | // Copyright (c) 2013 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSColor (ColorArithmetic) 12 | - (BOOL)isDark; 13 | - (NSColor *)colorByMutliplyingComponentsBy:(CGFloat)multiplier; 14 | @end 15 | -------------------------------------------------------------------------------- /Classes/NSAttributedString+Hyperlink.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+Hyperlink.h 3 | // Quark 4 | // 5 | // Created by Daniel on 09-12-17. 6 | // Copyright 2009 Macosope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSAttributedString (Hyperlink) 12 | + (NSAttributedString *)hyperlinkFromString:(NSString *)inString withURL:(NSURL *)aURL; 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/NSView+RoundedFrame.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+RoundedFrame.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/23/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSView (RoundedFrame) 12 | + (void)drawRoundedFrame:(NSRect)roundedFrame withRadius:(NSInteger)radius filledWithColor:(NSColor *)color; 13 | @end -------------------------------------------------------------------------------- /Classes/CPSearchFieldTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SearchFieldTextView.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/27/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CPSearchFieldTextView : NSTextView 12 | @property (nonatomic, assign) BOOL someKeyIsDown; 13 | - (void)pasteString:(NSString *)str; 14 | @end 15 | -------------------------------------------------------------------------------- /Classes/NSAppleEventDescriptor+ToObject.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSAppleEventDescriptor+ToObject.h 3 | // Quark 4 | // 5 | // Created by Daniel on 09-10-15. 6 | // Copyright 2009 Macosope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //http://github.com/Grayson/applescripttodictionarywithnutoo 12 | @interface NSAppleEventDescriptor (ToObject) 13 | - (id)toObject; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/NSURL+Anchors.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+Anchors.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 6/20/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "NSURL+Anchors.h" 10 | 11 | @implementation NSURL (Anchors) 12 | - (NSString *)pathWithoutAnchor 13 | { 14 | return [[[self path] componentsSeparatedByString:@"#"] objectAtIndex:0]; 15 | } 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/CPHUDViewWithRoundCorners.h: -------------------------------------------------------------------------------- 1 | // 2 | // HUDViewWithRoundCorners.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/11/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CPHUDViewWithRoundCorners : NSView 12 | @property (nonatomic, assign) NSUInteger cornerRadius; 13 | @property (nonatomic, strong) NSColor *backgroundColor; 14 | @end 15 | -------------------------------------------------------------------------------- /Classes/NSString+Abbreviation.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Abbreviation.h 3 | // Quark 4 | // 5 | // Created by Daniel on 09-12-04. 6 | // Copyright 2009 Macosope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (Abbreviation) 12 | - (NSArray *)hitsForString:(NSString *)testString; 13 | - (NSNumber *)scoreForQuery:(NSString *)query; 14 | - (BOOL)matchesFuzzyQuery:(NSString *)query; 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/CPResult.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPResult.h 3 | // CodePilot 4 | // 5 | // Created by Karol Kozub on 14.08.2013. 6 | // Copyright (c) 2013 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CPResult : NSObject 12 | - (NSString *)name; 13 | - (NSString *)sourceFile; 14 | - (double)scoreOffset; 15 | - (BOOL)isSearchable; 16 | - (BOOL)isOpenable; 17 | - (BOOL)isImplementation; 18 | @end 19 | -------------------------------------------------------------------------------- /Classes/NSArray+MiscExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MiscExtensions.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/9/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSArray (MiscExtensions) 12 | - (NSArray *)arrayScoresWithFuzzyQuery:(NSString *)query forKey:(NSString *)key; 13 | - (NSArray *)arrayWithoutElementsHavingNilOrEmptyValueForKey:(NSString *)key; 14 | @end 15 | -------------------------------------------------------------------------------- /Classes/CPSymbolCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPSymbolCache.h 3 | // CodePilot 4 | // 5 | // Created by karol on 5/11/12. 6 | // Copyright (c) 2012 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CPSymbol, IDEIndexSymbol; 12 | 13 | @interface CPSymbolCache : NSObject 14 | + (CPSymbolCache *)sharedInstance; 15 | 16 | - (CPSymbol *)symbolForIDEIndexSymbol:(IDEIndexSymbol *)ideIndexSymbol relatedFilePath:(NSString *)relatedFilePath; 17 | @end 18 | -------------------------------------------------------------------------------- /Classes/NSMutableArray+MiscExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+MiscExtensions.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/9/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMutableArray (MiscExtensions) 12 | - (NSArray *)arrayFilteredAndScoredWithFuzzyQuery:(NSString *)query forKey:(NSString *)key; 13 | - (void)filterWithFuzzyQuery:(NSString *)query forKey:(NSString *)key; 14 | @end -------------------------------------------------------------------------------- /Classes/CPResultTableViewColumn.h: -------------------------------------------------------------------------------- 1 | // 2 | // ResultTableViewColumn.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/15/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CPSymbolCell, CPFileReferenceCell; 12 | 13 | @interface CPResultTableViewColumn : NSTableColumn 14 | @property (nonatomic, strong) CPSymbolCell *symbolCell; 15 | @property (nonatomic, strong) CPFileReferenceCell *fileCell; 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/CPPreferencesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPPreferencesViewController.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 4/26/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CPPreferencesView; 12 | 13 | @interface CPPreferencesViewController : NSObject 14 | @property (nonatomic, strong) CPPreferencesView *view; 15 | 16 | - (void)setupFromDefaults; 17 | - (void)applyChanges; 18 | @end 19 | -------------------------------------------------------------------------------- /Classes/CPResultTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ResultTableView.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/14/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CPResultTableView : NSTableView 12 | @property (nonatomic, assign) BOOL extendedDisplay; 13 | @property (nonatomic, strong) NSString *fileQuery; 14 | @property (nonatomic, strong) NSString *symbolQuery; 15 | 16 | - (NSUInteger)requiredHeight; 17 | @end 18 | -------------------------------------------------------------------------------- /Classes/CPPreferencesView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPPreferencesView.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/10/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface CPPreferencesView : NSView 13 | @property (nonatomic, strong) NSButton *autocopyingSelectionCheckbox; 14 | @property (nonatomic, strong) NSButton *externalEditorCheckbox; 15 | 16 | - (id)initWithPreferredFrame; 17 | 18 | + (CGFloat)preferredWidth; 19 | + (CGFloat)preferredHeight; 20 | @end 21 | -------------------------------------------------------------------------------- /Classes/CPFirstRunWindowView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPFirstRunWindowView.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/19/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPFirstRunWindowView.h" 10 | #import "CPCodePilotConfig.h" 11 | 12 | @implementation CPFirstRunWindowView 13 | - (id)initWithFrame:(NSRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | 17 | if (self) { 18 | [self.infoLabel setStringValue:FIRST_RUN_INFO_STRING]; 19 | } 20 | 21 | return self; 22 | } 23 | @end 24 | -------------------------------------------------------------------------------- /Classes/NSNumber+VersionComparison.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSNumber+VersionComparison.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/19/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSNumber (VersionComparison) 12 | + (NSNumber *)numberWithVersionString:(NSString *)versionString; 13 | + (NSNumber *)numberWithVersionInt:(NSInteger)versionInt; 14 | + (NSNumber *)numberWithVersionNumber:(NSNumber *)n; 15 | + (NSNumber *)numberWithVersionLong:(long)versionLong; 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/CPWorkspaceSymbolCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPWorkspaceSymbolCache.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 5/20/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class IDEWorkspace; 12 | 13 | @interface CPWorkspaceSymbolCache : NSObject 14 | @property (nonatomic, copy) NSArray *symbols; 15 | @property (nonatomic, strong) IDEWorkspace *workspace; 16 | 17 | + (CPWorkspaceSymbolCache *)symbolCacheWithSymbols:(NSArray *)symbols forWorkspace:(IDEWorkspace *)workspace; 18 | @end 19 | -------------------------------------------------------------------------------- /Classes/CPNoProjectOpenWindowView.m: -------------------------------------------------------------------------------- 1 | // 2 | // NoProjectOpenWindowView.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/19/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPNoProjectOpenWindowView.h" 10 | #import "CPCodePilotConfig.h" 11 | 12 | @implementation CPNoProjectOpenWindowView 13 | - (id)initWithFrame:(NSRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | 17 | if (self) { 18 | [self.infoLabel setStringValue:NO_PROJECT_OPEN_INFO_STRING]; 19 | } 20 | 21 | return self; 22 | } 23 | @end 24 | -------------------------------------------------------------------------------- /Classes/CPInfoWindowView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPInfoWindowView.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/11/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPHUDViewWithRoundCorners.h" 11 | #import "CPStatusLabel.h" 12 | 13 | @interface CPInfoWindowView : CPHUDViewWithRoundCorners 14 | @property (nonatomic, strong) CPStatusLabel *infoLabel; 15 | @property (nonatomic, strong) NSURL *clickUrl; 16 | 17 | - (NSSize)windowFrameRequirements; 18 | - (void)setupInfoLabel; 19 | - (void)drawProductLogo; 20 | @end 21 | -------------------------------------------------------------------------------- /Classes/NSString+MiscExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+MiscExtensions.h 3 | // CodePilot 4 | // 5 | // Created by Daniel on 09-12-10. 6 | // Copyright 2009 Macosope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define MC_SED(string, pattern, replacement) [string replaceOccurrencesOfString:pattern withString:replacement options:0 range:NSMakeRange(0, [string length])] 12 | 13 | @interface NSString(MiscExtensions) 14 | - (BOOL)isBlank; 15 | - (NSRange)completeRange; 16 | - (NSString *)hexString; 17 | + (NSString *)nounWithCount:(NSInteger)count forNoun:(NSString *)noun; 18 | @end -------------------------------------------------------------------------------- /Classes/CPFileReferenceCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FileSelectionCell.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/10/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPResultCell.h" 11 | 12 | @class CPFileReference; 13 | 14 | @interface CPFileReferenceCell : CPResultCell 15 | @property (nonatomic, strong, readonly) CPFileReference *cpFileReference; 16 | 17 | - (NSUInteger)requiredHeight; 18 | - (void)drawFileNameWithFrame:(NSRect)cellFrame; 19 | - (void)drawGroupNameWithFrame:(NSRect)cellFrame; 20 | - (void)drawIconWithFrame:(NSRect)cellFrame; 21 | @end 22 | -------------------------------------------------------------------------------- /Classes/NSURL+Xcode.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+Xcode.m 3 | // CodePilot 4 | // 5 | // Created by Fjölnir Ásgeirsson on 2/2/14. 6 | // Copyright (c) 2014 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "NSURL+Xcode.h" 10 | 11 | @implementation NSURL (Xcode) 12 | 13 | - (BOOL)cp_opensInXcode 14 | { 15 | NSURL *appURL = [[NSWorkspace sharedWorkspace] URLForApplicationToOpenURL:self]; 16 | if(appURL) { 17 | NSBundle *appBundle = [NSBundle bundleWithURL:appURL]; 18 | NSBundle *xcodeBundle = [NSBundle mainBundle]; 19 | return [appBundle.bundleIdentifier isEqualToString:xcodeBundle.bundleIdentifier]; 20 | } 21 | return NO; 22 | } 23 | @end 24 | -------------------------------------------------------------------------------- /Classes/CPHUDViewWithRoundCorners.m: -------------------------------------------------------------------------------- 1 | // 2 | // HUDViewWithRoundCorners.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/11/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPHUDViewWithRoundCorners.h" 10 | #import "NSView+RoundedFrame.h" 11 | 12 | @implementation CPHUDViewWithRoundCorners 13 | - (void)drawRect:(NSRect)rect 14 | { 15 | [[NSColor clearColor] setFill]; 16 | NSRectFill(self.frame); 17 | 18 | [NSView drawRoundedFrame:self.frame 19 | withRadius:self.cornerRadius 20 | filledWithColor:self.backgroundColor]; 21 | } 22 | 23 | - (BOOL)isOpaque 24 | { 25 | return NO; 26 | } 27 | @end 28 | -------------------------------------------------------------------------------- /Classes/CPWorkspaceSymbolCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPWorkspaceSymbolCache.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 5/20/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPWorkspaceSymbolCache.h" 10 | 11 | // holds symbol cache for particular workspace 12 | @implementation CPWorkspaceSymbolCache 13 | 14 | + (CPWorkspaceSymbolCache *)symbolCacheWithSymbols:(NSArray *)symbols forWorkspace:(IDEWorkspace *)workspace 15 | { 16 | CPWorkspaceSymbolCache *newCache = [[CPWorkspaceSymbolCache alloc] init]; 17 | newCache.workspace = workspace; 18 | newCache.symbols = symbols; 19 | 20 | return newCache; 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /MCCommons/MCCommons.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCCommons.h 3 | // Macoscope Commons Library 4 | // 5 | // Created by Daniel on 08-11-03. 6 | // Copyright 2008 Macosope. All rights reserved. 7 | // 8 | 9 | #import "MCLog.h" 10 | #import "NSString+MiscExtensions.h" 11 | 12 | 13 | #ifndef NSNotFoundRange 14 | # define NSNotFoundRange ((NSRange) {.location = NSNotFound, .length = 0UL}) 15 | #endif 16 | 17 | static inline BOOL IsEmpty(id thing) { 18 | return thing == nil 19 | || ([NSNull null]==thing) 20 | || ([thing respondsToSelector:@selector(length)] && [(NSData *)thing length] == 0) 21 | || ([thing respondsToSelector:@selector(count)] && [(NSArray *)thing count] == 0); 22 | } 23 | -------------------------------------------------------------------------------- /Installer/resources/en.lproj/Welcome.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1187 2 | \cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 LucidaGrande;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw11900\paperh16840\margl1440\margr1440\vieww10500\viewh9600\viewkind0 5 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc 6 | 7 | \f0\fs28 \cf0 \ 8 | \ 9 | This Code Pilot 3.0 for Xcode 5.x \ 10 | \ 11 | Thank you for downloading Code Pilot\ 12 | \ 13 | \ 14 | 15 | \b After installing Code Pilot, you will see Code Pilot\ 16 | option in "File" menu of your Xcode 5 installation\ 17 | 18 | \b0 \ 19 | \ 20 | \ul Please quit your Xcode before proceeding 21 | \b \ulnone \ 22 | \ 23 | } -------------------------------------------------------------------------------- /Classes/CPPreferencesToolbarDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPPreferencesToolbarDelegate.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 4/23/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class IDEPreferencesController, CPPreferencesViewController; 12 | 13 | @interface CPPreferencesToolbarDelegate : NSObject 14 | + (CPPreferencesToolbarDelegate *)preferencesToolbarDelegateByInterceptingDelegateOfToolbar:(NSToolbar *)toolbar; 15 | 16 | - (id)initWithOriginalToolbarDelegate:(IDEPreferencesController *)_originalDelegate toolbar:(NSToolbar *)toolbar; 17 | - (void)prepareToolbarItem; 18 | - (void)ourItemWasSelected:(id)sender; 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/CPSymbolCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPSymbolCell.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/15/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPResultCell.h" 11 | 12 | @class CPSymbol; 13 | 14 | @interface CPSymbolCell : CPResultCell 15 | @property (nonatomic, strong, readonly) CPSymbol *cpSymbol; 16 | 17 | - (NSUInteger)requiredHeight; 18 | - (NSColor *)symbolNameForegroundColor; 19 | - (void)drawSymbolNameWithFrame:(NSRect)cellFrame; 20 | - (void)drawSourceFileNameWithFrame:(NSRect)cellFrame; 21 | - (NSColor *)symbolCategoryNameForegroundColor; 22 | - (NSColor *)symbolNameForegroundColorWithoutHighlight; 23 | - (NSColor *)symbolNameForegroundColorWithHighlight; 24 | @end -------------------------------------------------------------------------------- /Classes/CPXcodeVersionUnsupportedWindowView.m: -------------------------------------------------------------------------------- 1 | // 2 | // XcodeVersionUnsupportedWindowView.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/19/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPXcodeVersionUnsupportedWindowView.h" 10 | #import "CPCodePilotConfig.h" 11 | 12 | @implementation CPXcodeVersionUnsupportedWindowView 13 | - (id)initWithFrame:(NSRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | 17 | if (self) { 18 | self.infoLabel.stringValue = CURRENT_XCODE_VERSION_UNSUPPORTED_INFO_STRING; 19 | self.infoLabel.clickUrl = [NSURL URLWithString:PRODUCT_BUY_LINK]; 20 | self.clickUrl = [NSURL URLWithString:PRODUCT_BUY_LINK]; 21 | } 22 | 23 | return self; 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /Classes/CPResultScrollView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPResultScrollView.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 5/26/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPResultScrollView.h" 10 | 11 | @implementation CPResultScrollView 12 | - (void)tile 13 | { 14 | [super tile]; 15 | 16 | // makes clipview wider, so we get an overlay scrollbar 17 | for (NSView *subview in [self subviews]) { 18 | if ([subview isKindOfClass:[NSClipView class]]) { 19 | subview.frame = NSMakeRect(subview.frame.origin.x, 20 | subview.frame.origin.y, 21 | self.frame.size.width, 22 | subview.frame.size.height); 23 | } 24 | } 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/CPResultCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ResultCell.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/2/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface CPResultCell : NSTextFieldCell 13 | @property (nonatomic, assign) BOOL extendedDisplay; 14 | @property (nonatomic, strong) NSString *query; 15 | 16 | - (NSParagraphStyle *)defaultParagraphStyle; 17 | - (NSDictionary *)characterHitExtraAttributes; 18 | - (NSDictionary *)defaultStringAttributes; 19 | - (NSAttributedString *)queryHitAttributedStringWithString:(NSString *)subjectString; 20 | - (void)drawIconImage:(NSImage *)icon withFrame:(NSRect)cellFrame; 21 | - (void)drawWithBackgroundImageNamed:(NSString *)backgroundImageName withFrame:(NSRect)cellFrame; 22 | @end -------------------------------------------------------------------------------- /Classes/CPCodePilotWindowDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPCodePilotWindowDelegate.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/9/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CPWindow; 12 | @class CPSearchController; 13 | @class CPSearchFieldTextView; 14 | 15 | @interface CPCodePilotWindowDelegate : NSObject 16 | @property (nonatomic, strong) IBOutlet CPWindow *window; 17 | @property (nonatomic, strong) IBOutlet CPSearchController *searchController; 18 | @property (nonatomic, assign) BOOL ourWindowIsOpen; 19 | @property (nonatomic, strong) CPSearchFieldTextView *searchFieldTextEditor; 20 | 21 | - (id)initWithXcodeWrapper:(CPXcodeWrapper *)xcodeWrapper; 22 | 23 | - (void)openWindow; 24 | - (void)hideWindow; 25 | - (void)openFirstRunWindow; 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/CPXcodeInterfaces.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPXcodeInterfaces.m 3 | // CodePilot 4 | // 5 | // Created by Karol Kozub on 22.07.2013. 6 | // Copyright (c) 2013 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPXcodeInterfaces.h" 10 | 11 | @implementation IDEWorkspaceWindow (MissingMethods) 12 | + (IDEWorkspaceWindow *)mc_lastActiveWorkspaceWindow 13 | { 14 | if ([self respondsToSelector:@selector(lastActiveWorkspaceWindow)]) { 15 | return [self performSelector:@selector(lastActiveWorkspaceWindow)]; 16 | } 17 | 18 | if ([self respondsToSelector:@selector(lastActiveWorkspaceWindowController)]) { 19 | IDEWorkspaceWindowController *workspaceWindowController = [self performSelector:@selector(lastActiveWorkspaceWindowController)]; 20 | 21 | return (IDEWorkspaceWindow *)[workspaceWindowController window]; 22 | } 23 | 24 | return nil; 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/CPWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // SearchWindow.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/14/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CPSearchWindowView, CPNoProjectOpenWindowView, CPXcodeVersionUnsupportedWindowView, CPFirstRunWindowView; 12 | 13 | @interface CPWindow : NSWindow 14 | @property (nonatomic, strong) CPSearchWindowView *searchWindowView; 15 | @property (nonatomic, strong) CPNoProjectOpenWindowView *noProjectOpenWindowView; 16 | @property (nonatomic, strong) CPXcodeVersionUnsupportedWindowView *xcodeVersionUnsupportedWindowView; 17 | @property (nonatomic, strong) CPFirstRunWindowView *firstRunWindowView; 18 | 19 | - (void)updateFrameWithViewRequirementsWithAnimation:(BOOL)animation; 20 | - (void)updateFrameWithViewRequirements; 21 | - (id)initWithDefaultSettings; 22 | - (void)firstRunOrderFront; 23 | - (NSScreen *)destinationScreen; 24 | @end -------------------------------------------------------------------------------- /Classes/CPStatusLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // StatusLabel.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/20/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPStatusLabel.h" 10 | 11 | @implementation CPStatusLabel 12 | - (id)initWithFrame:(NSRect)frameRect 13 | { 14 | self = [super initWithFrame:frameRect]; 15 | 16 | if (self) { 17 | [self setBackgroundColor:[NSColor clearColor]]; 18 | [self setTextColor:[NSColor grayColor]]; 19 | [self setBordered:NO]; 20 | [self setEditable:NO]; 21 | [self setSelectable:NO]; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | - (BOOL)acceptsFirstResponder 28 | { 29 | return NO; 30 | } 31 | 32 | - (void)mouseDown:(NSEvent *)theEvent 33 | { 34 | if (self.clickUrl) { 35 | [[NSWorkspace sharedWorkspace] openURL:self.clickUrl]; 36 | } 37 | } 38 | 39 | - (CGFloat)textWidth 40 | { 41 | return [[self attributedStringValue] size].width; 42 | } 43 | @end -------------------------------------------------------------------------------- /Classes/AMIndeterminateProgressIndicatorCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // AMIndeterminateProgressIndicatorCell.h 3 | // IPICellTest 4 | // 5 | // Created by Andreas on 23.01.07. 6 | // Copyright 2007 Andreas Mayer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface AMIndeterminateProgressIndicatorCell : NSCell { 13 | double doubleValue; 14 | NSTimeInterval animationDelay; 15 | BOOL displayedWhenStopped; 16 | BOOL spinning; 17 | NSColor *color; 18 | CGFloat redComponent; 19 | CGFloat greenComponent; 20 | CGFloat blueComponent; 21 | } 22 | 23 | - (NSColor *)color; 24 | - (void)setColor:(NSColor *)value; 25 | 26 | - (double)doubleValue; 27 | - (void)setDoubleValue:(double)value; 28 | 29 | - (NSTimeInterval)animationDelay; 30 | - (void)setAnimationDelay:(NSTimeInterval)value; 31 | 32 | - (BOOL)isDisplayedWhenStopped; 33 | - (void)setDisplayedWhenStopped:(BOOL)value; 34 | 35 | - (BOOL)isSpinning; 36 | - (void)setSpinning:(BOOL)value; 37 | 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Classes/NSView+AllSubviews.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+AllSubviews.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/23/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "NSView+AllSubviews.h" 10 | 11 | @implementation NSView (AllSubviews) 12 | - (NSArray *)allSubviews 13 | { 14 | NSMutableArray *mySubviews = [NSMutableArray new]; 15 | 16 | for (NSView *view in [self subviews]) { 17 | if ([[view subviews] count] > 0) { 18 | [mySubviews addObjectsFromArray:[view allSubviews]]; 19 | } 20 | 21 | [mySubviews addObject:view]; 22 | } 23 | 24 | return mySubviews; 25 | } 26 | 27 | - (NSArray *)allSubviewsOfClass:(Class)klass 28 | { 29 | NSArray *allSubviews = [self allSubviews]; 30 | NSMutableArray *subviewsOfClass = [NSMutableArray new]; 31 | 32 | for (NSView *subview in allSubviews) { 33 | if ([subview isKindOfClass:klass]) { 34 | [subviewsOfClass addObject:subview]; 35 | } 36 | } 37 | 38 | return subviewsOfClass; 39 | } 40 | @end 41 | -------------------------------------------------------------------------------- /Classes/CPPreferencesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPPreferencesViewController.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 4/26/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPPreferencesViewController.h" 10 | #import "CPPreferencesView.h" 11 | 12 | @implementation CPPreferencesViewController 13 | - (id)init 14 | { 15 | self = [super init]; 16 | 17 | if (self) { 18 | self.view = [[CPPreferencesView alloc] initWithPreferredFrame]; 19 | } 20 | 21 | return self; 22 | } 23 | 24 | - (void)setupFromDefaults 25 | { 26 | } 27 | 28 | - (void)applyChanges 29 | { 30 | BOOL autocopySelectionValue = [self.view.autocopyingSelectionCheckbox state]; 31 | [[NSUserDefaults standardUserDefaults] setBool:autocopySelectionValue forKey:DEFAULTS_AUTOCOPY_SELECTION_KEY]; 32 | 33 | BOOL externalEditorValue = [self.view.externalEditorCheckbox state]; 34 | [[NSUserDefaults standardUserDefaults] setBool:externalEditorValue forKey:DEFAULTS_EXTERNAL_EDITOR_KEY]; 35 | } 36 | 37 | @end -------------------------------------------------------------------------------- /Classes/CPSearchField.h: -------------------------------------------------------------------------------- 1 | // 2 | // SearchField.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/27/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CPStatusLabel, CPSearchFieldTextView, CPResult; 12 | 13 | @interface CPSearchField : NSTextField 14 | @property (nonatomic, strong) NSString *fileQuery; 15 | @property (nonatomic, strong) NSString *symbolQuery; 16 | @property (nonatomic, weak) NSTimer *delegateNotificationAboutChangedQueriesTimer; 17 | @property (nonatomic, strong) CPResult *selectedObject; 18 | @property (nonatomic, assign) CGFloat delay; 19 | @property (nonatomic, strong) CPStatusLabel *placeholderTextField; 20 | 21 | - (BOOL)spaceKeyDown; 22 | - (void)reset; 23 | - (id)copyWithZone:(NSZone *)zone; 24 | - (void)disableObservers; 25 | - (void)letDelegateKnowAboutChangedQueries; 26 | - (void)setupDelegateNotificationAboutChangedQueriesTimer; 27 | - (void)selectedObjectDidChange; 28 | - (BOOL)cmdBackspaceKeyDown; 29 | - (void)pasteString:(NSString *)str; 30 | @end -------------------------------------------------------------------------------- /Classes/NSAttributedString+Hyperlink.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+Hyperlink.m 3 | // Quark 4 | // 5 | // Created by Daniel on 09-12-17. 6 | // Copyright 2009 Macosope. All rights reserved. 7 | // 8 | 9 | #import "NSAttributedString+Hyperlink.h" 10 | 11 | @implementation NSAttributedString (Hyperlink) 12 | + (NSAttributedString *)hyperlinkFromString:(NSString *)inString withURL:(NSURL *)aURL 13 | { 14 | NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:inString]; 15 | NSRange range = NSMakeRange(0, [attrString length]); 16 | 17 | [attrString beginEditing]; 18 | [attrString addAttributes:@{NSLinkAttributeName: [aURL absoluteString], 19 | NSToolTipAttributeName: [aURL absoluteString], 20 | NSForegroundColorAttributeName: [NSColor blueColor], 21 | NSUnderlineStyleAttributeName: @(NSSingleUnderlineStyle)} 22 | range:range]; 23 | [attrString endEditing]; 24 | 25 | return attrString; 26 | } 27 | @end 28 | -------------------------------------------------------------------------------- /Classes/CPResult.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPResult.m 3 | // CodePilot 4 | // 5 | // Created by Karol Kozub on 14.08.2013. 6 | // Copyright (c) 2013 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPResult.h" 10 | 11 | @implementation CPResult 12 | - (NSString *)name 13 | { 14 | [self doesNotRecognizeSelector:_cmd]; 15 | return nil; 16 | } 17 | 18 | - (NSString *)sourceFile 19 | { 20 | [self doesNotRecognizeSelector:_cmd]; 21 | return nil; 22 | } 23 | 24 | - (double)scoreOffset 25 | { 26 | [self doesNotRecognizeSelector:_cmd]; 27 | return 0; 28 | } 29 | 30 | - (BOOL)isSearchable 31 | { 32 | [self doesNotRecognizeSelector:_cmd]; 33 | return NO; 34 | } 35 | 36 | - (BOOL)isOpenable 37 | { 38 | [self doesNotRecognizeSelector:_cmd]; 39 | return NO; 40 | } 41 | 42 | - (BOOL)isImplementation 43 | { 44 | NSArray *extensions = @[@".m", @".c", @".cpp", @".cc", @".mm"]; 45 | for (NSString *extension in extensions) { 46 | if ([[self sourceFile] hasSuffix:extension]) { 47 | return YES; 48 | } 49 | } 50 | 51 | return NO; 52 | } 53 | @end 54 | -------------------------------------------------------------------------------- /Classes/CPCodePilotPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPCodePilotPlugin.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/18/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CPCodePilotWindowDelegate, CPXcodeWrapper, PBXGroup, CPPluginInstaller; 12 | 13 | @interface CPCodePilotPlugin : NSObject 14 | @property (nonatomic, strong) CPXcodeWrapper *xcWrapper; 15 | @property (nonatomic, strong) CPCodePilotWindowDelegate *windowDelegate; 16 | @property (nonatomic, strong) CPPluginInstaller *installer; 17 | @property (nonatomic, strong) NSString *userKeyEquivalent; 18 | @property (nonatomic, assign) BOOL thisVersionFirstRun; 19 | @property (nonatomic, assign) BOOL firstRunEver; 20 | @property (nonatomic, assign) BOOL isUserLevelDebugOn; 21 | @property (nonatomic, assign) BOOL isInDocumentationMode; 22 | @property (nonatomic, assign) unsigned long long userKeyEquivalentModifierMask; 23 | 24 | + (instancetype)sharedInstance; 25 | + (void)pluginDidLoad:(id)arg1; 26 | 27 | - (void)openCodePilotWindow; 28 | - (void)checkForFirstRun; 29 | @end -------------------------------------------------------------------------------- /Classes/NSArray+MiscExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MiscExtensions.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/9/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "NSArray+MiscExtensions.h" 10 | #import "NSString+Abbreviation.h" 11 | 12 | @implementation NSArray (MiscExtensions) 13 | 14 | 15 | - (NSArray *)arrayScoresWithFuzzyQuery:(NSString *)query forKey:(NSString *)key 16 | { 17 | NSMutableArray *scores = [NSMutableArray new]; 18 | 19 | for (id obj in self) { 20 | NSNumber *score = [[obj valueForKey:key] scoreForQuery:query]; 21 | 22 | [scores addObject:score ?: [NSNull null]]; 23 | } 24 | 25 | return scores; 26 | } 27 | 28 | - (NSArray *)arrayWithoutElementsHavingNilOrEmptyValueForKey:(NSString *)key 29 | { 30 | NSMutableIndexSet *selectedIndexes = [NSMutableIndexSet new]; 31 | 32 | for (NSUInteger i = 0; i < [self count]; i++) { 33 | id obj = [self objectAtIndex:i]; 34 | 35 | if (!IsEmpty([obj valueForKey:key])) { 36 | [selectedIndexes addIndex:i]; 37 | } 38 | } 39 | 40 | return [self objectsAtIndexes:selectedIndexes]; 41 | } 42 | @end 43 | -------------------------------------------------------------------------------- /scripts/replace_plugin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | PROJECT_ROOT="$(cd "$(dirname "$0")" && cd .. && pwd)" 6 | 7 | CODE_PILOT_PROJ_PATH="$PROJECT_ROOT/CodePilot.xcodeproj" 8 | 9 | XCODE_PROC_NAME="Xcode" 10 | XCODE_APP_PATH="/Applications/Xcode.app" 11 | 12 | PLUGIN_NAME="CodePilot3.xcplugin" 13 | PLUGIN_SRC="$(echo ~/Library/Developer/Xcode/DerivedData/CodePilot-*/Build/Products/Debug)" 14 | PLUGIN_DEST="$(echo ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins)" 15 | 16 | echo Building the plugin 17 | xcodebuild -project "$CODE_PILOT_PROJ_PATH" -configuration Debug -scheme CodePilot 18 | 19 | echo Making sure the plugin directory exists 20 | mkdir -p "$PLUGIN_DEST" 21 | 22 | echo Removing the old plugin if there is one 23 | rm -rf "$PLUGIN_DEST/$PLUGIN_NAME" 24 | 25 | echo Copying the new plugin into the plugin directory 26 | cp -R "$PLUGIN_SRC/$PLUGIN_NAME" "$PLUGIN_DEST/" 27 | 28 | echo Closing Xcode 29 | if ! killall "$XCODE_PROC_NAME"; then 30 | echo Xcode wasnt open 31 | fi 32 | 33 | echo Reopening Xcode 34 | 35 | for i in `seq 3`; do 36 | sleep 1 37 | echo -ne . 38 | done 39 | 40 | echo 41 | 42 | open "$XCODE_APP_PATH" 43 | 44 | echo CodePilot plugin replaced successfully 45 | -------------------------------------------------------------------------------- /Classes/NSNumber+VersionComparison.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSNumber+VersionComparison.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/19/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "NSNumber+VersionComparison.h" 10 | 11 | @implementation NSNumber (VersionComparison) 12 | + (NSNumber *)numberWithVersionString:(NSString *)versionString 13 | { 14 | NSArray *parts = [versionString componentsSeparatedByString:@"."]; 15 | 16 | long bigNumber = 0; 17 | long powerOfTheMultiplier = 9; 18 | 19 | for (NSString *part in parts) { 20 | NSInteger partInt = [part integerValue]; 21 | 22 | if (partInt > 0) { 23 | bigNumber += partInt * pow(10, powerOfTheMultiplier); 24 | } 25 | 26 | powerOfTheMultiplier -= 2; 27 | } 28 | 29 | return [NSNumber numberWithVersionLong:bigNumber]; 30 | } 31 | 32 | + (NSNumber *)numberWithVersionLong:(long)versionLong 33 | { 34 | return [NSNumber numberWithLong:versionLong]; 35 | } 36 | 37 | + (NSNumber *)numberWithVersionInt:(NSInteger)versionInt 38 | { 39 | return [NSNumber numberWithInt:versionInt]; 40 | } 41 | 42 | + (NSNumber *)numberWithVersionNumber:(NSNumber *)n 43 | { 44 | return [NSNumber numberWithInt:[n intValue]]; 45 | } 46 | @end 47 | -------------------------------------------------------------------------------- /Classes/CPFileReference.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPFileReference.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/15/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPResult.h" 11 | 12 | @interface CPFileReference : CPResult 13 | @property (nonatomic, strong) NSString *fileName; 14 | @property (nonatomic, strong) NSString *groupName; 15 | @property (nonatomic, strong) NSString *absolutePath; 16 | @property (nonatomic, strong) NSImage *icon; 17 | @property (nonatomic, strong) NSURL *fileURL; 18 | @property (nonatomic, strong) NSString *projectName; 19 | @property (nonatomic, assign) BOOL subprojectFile; 20 | @property (nonatomic, strong) NSString *originalClassName; 21 | @property (nonatomic, assign) BOOL isGroup; 22 | @property (nonatomic, assign) BOOL isOpenable; 23 | @property (nonatomic, assign) BOOL isSearchable; 24 | @property (nonatomic, assign) BOOL isOpenableInEditor; 25 | 26 | - (CPFileReference *)initWithPBXFileReference:(PBXFileReference *)pbxFileReference; 27 | - (CPFileReference *)initWithFileURL:(NSURL *)_fileURL; 28 | - (NSString *)name; 29 | - (BOOL)isEqualToPbxReference:(PBXFileReference *)pbxReference; 30 | + (BOOL)pbxFileReferenceIsImportable:(PBXFileReference *)pbxFileReference; 31 | - (CPFileReference *)initWithDVTFilePath:(DVTFilePath *)_filePath; 32 | @end -------------------------------------------------------------------------------- /Installer/resources/en.lproj/ReadMe.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 2 | \cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 LucidaGrande;} 3 | {\colortbl;\red255\green255\blue255;} 4 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}} 5 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}} 6 | \paperw11900\paperh16840\margl1440\margr1440\vieww32180\viewh16480\viewkind0 7 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural 8 | 9 | \f0\fs26 \cf0 \ 10 | 11 | \b CodePilot is currently an open source project hosted and developed on github. It was originally created by Macoscope Sp. z o.o.\ 12 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural 13 | 14 | \fs36 \cf0 \ 15 | Changelog\ 16 | \ 17 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural 18 | 19 | \fs28 \cf0 Version 3.0\ 20 | \ 21 | \pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural 22 | \ls1\ilvl0 23 | \b0\fs26 \cf0 \'95 Xcode 5 support\ 24 | } -------------------------------------------------------------------------------- /Classes/CPSymbol.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPSymbol.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/15/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPResult.h" 11 | 12 | @class CPFileReference, IDEIndexSymbolOccurrence; 13 | 14 | @interface CPSymbol : CPResult 15 | @property (nonatomic, strong) IDEIndexSymbol *wrappedObject; 16 | @property (nonatomic, strong) NSString *relatedFilePath; 17 | @property (nonatomic, strong) NSString *categoryName; 18 | @property (nonatomic, strong) NSArray *childrenCache; 19 | @property (nonatomic, assign, readonly) BOOL hasOccurrences; 20 | @property (nonatomic, strong) IDEIndexSymbolOccurrence *cachedRelatedSymbolOccurrence; 21 | 22 | - (CPSymbol *)initWithIDEIndexSymbol:(IDEIndexSymbol *)ideIndexSymbol forRelatedFileAtPath:(NSString *)relatedFilePath; 23 | - (CPSymbol *)initWithIDEIndexSymbol:(IDEIndexSymbol *)ideIndexSymbol forCPFileReference:(CPFileReference *)fileReference; 24 | 25 | - (BOOL)isEqualToIDEIndexSymbol:(IDEIndexSymbol *)ideIndexSymbol; 26 | - (BOOL)isCategory; 27 | 28 | - (NSString *)symbolTypeName; 29 | - (NSString *)name; 30 | - (NSString *)sourceFile; 31 | - (NSString *)originalClassName; 32 | - (NSImage *)icon; 33 | 34 | - (void)logOccurrences; 35 | - (DVTTextDocumentLocation *)relatedDocumentLocation; 36 | - (IDEIndexSymbolOccurrence *)relatedSymbolOccurrence; 37 | - (NSArray *)children; 38 | 39 | - (void)cacheRelatedSymbolOccurrence; 40 | @end -------------------------------------------------------------------------------- /Classes/NSColor+ColorArithmetic.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+ColorArithmetic.m 3 | // CodePilot 4 | // 5 | // Created by Karol Kozub on 08.08.2013. 6 | // Copyright (c) 2013 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "NSColor+ColorArithmetic.h" 10 | 11 | static const NSInteger NumberOfComponents = 4; 12 | static const NSInteger NumberOfComponentsWithoutAlpha = 3; 13 | static const CGFloat ComponentIsDarkBoundary = 0.4; 14 | 15 | @implementation NSColor (ColorArithmetic) 16 | - (BOOL)isDark 17 | { 18 | CGFloat components[NumberOfComponents]; 19 | 20 | [self getCalibratedComponents:components]; 21 | 22 | for (NSInteger i = 0; i < NumberOfComponentsWithoutAlpha; i++) { 23 | if (components[i] >= ComponentIsDarkBoundary) { 24 | return NO; 25 | } 26 | } 27 | 28 | return YES; 29 | } 30 | 31 | - (NSColor *)colorByMutliplyingComponentsBy:(CGFloat)multiplier 32 | { 33 | CGFloat components[NumberOfComponents]; 34 | 35 | [self getCalibratedComponents:components]; 36 | 37 | for (NSInteger i = 0; i < NumberOfComponentsWithoutAlpha; i++) { 38 | components[i] = MIN(1, MAX(0, components[i] * multiplier)); 39 | } 40 | 41 | return [NSColor colorWithCalibratedRed:components[0] green:components[1] blue:components[2] alpha:components[3]]; 42 | } 43 | 44 | - (void)getCalibratedComponents:(CGFloat *)components 45 | { 46 | [[self colorUsingColorSpaceName:@"NSCalibratedRGBColorSpace"] getComponents:components]; 47 | } 48 | @end 49 | -------------------------------------------------------------------------------- /Classes/CPSelectedObjectCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SelectedObjectCell.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/28/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CPSelectedObjectCell : NSTextAttachmentCell 12 | @property (nonatomic, assign) NSPoint cellBaselineOffset; 13 | @property (nonatomic, assign) NSSize cellSize; 14 | @property (nonatomic, strong) NSDictionary *stringAttributes; 15 | 16 | - (NSRect)cellFrameForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(NSRect)lineFrag glyphPosition:(NSPoint)position characterIndex:(NSUInteger)charIndex; 17 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView; 18 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)aView characterIndex:(NSUInteger)charIndex; 19 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView characterIndex:(NSUInteger)charIndex layoutManager:(NSLayoutManager *)layoutManager; 20 | - (void)highlight:(BOOL)flag withFrame:(NSRect)cellFrame inView:(NSView *)aView; 21 | - (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)aTextView atCharacterIndex:(NSUInteger)charIndex untilMouseUp:(BOOL)flag; 22 | - (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)aTextView untilMouseUp:(BOOL)flag; 23 | - (BOOL)wantsToTrackMouse; 24 | - (BOOL)wantsToTrackMouseForEvent:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView atCharacterIndex:(NSUInteger)charIndex; 25 | @end 26 | -------------------------------------------------------------------------------- /Installer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | net.macoscope.CodePilot3.pkg 7 | IFPkgFlagAllowBackRev 8 | 9 | IFPkgFlagAuthorizationAction 10 | NoAuthorization 11 | IFPkgFlagBackgroundAlignment 12 | bottomleft 13 | IFPkgFlagBackgroundScaling 14 | none 15 | IFPkgFlagDefaultLocation 16 | /tmp 17 | IFPkgFlagFollowLinks 18 | 19 | IFPkgFlagInstallFat 20 | 21 | IFPkgFlagInstalledSize 22 | 1440 23 | IFPkgFlagIsRequired 24 | 25 | IFPkgFlagOverwritePermissions 26 | 27 | IFPkgFlagRelocatable 28 | 29 | IFPkgFlagRestartAction 30 | NoRestart 31 | IFPkgFlagRootVolumeOnly 32 | 33 | IFPkgFlagUpdateInstalledLanguages 34 | 35 | IFPkgFormatVersion 36 | 0.1000000014901161 37 | International 38 | 39 | Keywords 40 | 41 | Mode 42 | 0 43 | Path 44 | 45 | Path Type 46 | 1 47 | Template 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Classes/NSMutableArray+MiscExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+MiscExtensions.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/9/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "NSArray+MiscExtensions.h" 10 | #import "NSMutableArray+MiscExtensions.h" 11 | #import "NSString+Abbreviation.h" 12 | 13 | @implementation NSMutableArray (MiscExtensions) 14 | // filters entries not matching to the query 15 | // and returns score table for what's left 16 | - (NSArray *)arrayFilteredAndScoredWithFuzzyQuery:(NSString *)query forKey:(NSString *)key 17 | { 18 | NSMutableArray *scores = [[self arrayScoresWithFuzzyQuery:query forKey:key] mutableCopy]; 19 | NSMutableIndexSet *indexesToRemove = [NSMutableIndexSet new]; 20 | 21 | for (NSInteger i = 0; i < [self count]; i++) { 22 | if ([NSNull null] == [scores objectAtIndex:i]) { 23 | [indexesToRemove addIndex:i]; 24 | } 25 | } 26 | 27 | [self removeObjectsAtIndexes:indexesToRemove]; 28 | [scores removeObjectsAtIndexes:indexesToRemove]; 29 | 30 | return scores; 31 | } 32 | 33 | // simpler/faster implementation when you don't need scoring 34 | - (void)filterWithFuzzyQuery:(NSString *)query forKey:(NSString *)key 35 | { 36 | NSMutableIndexSet *indexesToRemove = [NSMutableIndexSet new]; 37 | 38 | for (NSInteger i = 0; i < [self count]; i++) { 39 | id obj = [self objectAtIndex:i]; 40 | if (![[obj valueForKey:key] matchesFuzzyQuery:query]) { 41 | [indexesToRemove addIndex:i]; 42 | } 43 | } 44 | 45 | [self removeObjectsAtIndexes:indexesToRemove]; 46 | } 47 | @end -------------------------------------------------------------------------------- /Classes/NSString+MiscExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+MiscExtensions.m 3 | // Quark 4 | // 5 | // Created by Daniel on 09-12-10. 6 | // Copyright 2009 Macosope. All rights reserved. 7 | // 8 | 9 | #import "NSString+MiscExtensions.h" 10 | 11 | @implementation NSString (MiscExtensions) 12 | - (BOOL)isBlank 13 | { 14 | NSRange spaceRange = [self rangeOfCharacterFromSet:[[NSCharacterSet whitespaceAndNewlineCharacterSet] invertedSet]]; 15 | return spaceRange.length == 0; 16 | } 17 | 18 | - (NSRange)completeRange 19 | { 20 | return NSMakeRange(0, [self length]); 21 | } 22 | 23 | - (NSString *)hexString 24 | { 25 | char hexbuf[100]; 26 | const char *selfString = [self UTF8String]; 27 | 28 | memset(hexbuf, 0, 100); 29 | 30 | for (int i = 0; i < [self length] && i < 100; i++) { 31 | sprintf((char *)&(hexbuf[i*2]),"%02x",selfString[i]); 32 | } 33 | 34 | return [NSString stringWithCString:hexbuf encoding:NSUTF8StringEncoding]; 35 | } 36 | 37 | // this just handles singular/plural distinction in a stupid way 38 | + (NSString *)nounWithCount:(NSInteger)count forNoun:(NSString *)noun 39 | { 40 | NSString *format; 41 | 42 | if (ABS(count) != 1) { 43 | // s, z, x, sh, and ch 44 | if ([noun hasSuffix:@"s"] || 45 | [noun hasSuffix:@"z"] || 46 | [noun hasSuffix:@"x"] || 47 | [noun hasSuffix:@"sh"] || 48 | [noun hasSuffix:@"ch"]) { 49 | format = @"%d %@es"; 50 | } else { 51 | format = @"%d %@s"; 52 | } 53 | } else { 54 | format = @"%d %@"; 55 | } 56 | 57 | return [NSString stringWithFormat:format, count, noun]; 58 | } 59 | @end -------------------------------------------------------------------------------- /Classes/CPPluginInstaller.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPPluginInstaller.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/23/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CPCodePilotPlugin, SUUpdater, CPPreferencesToolbarDelegate; 12 | 13 | @interface CPPluginInstaller : NSObject 14 | @property (nonatomic, strong) CPCodePilotPlugin *installedPlugin; 15 | @property (nonatomic, strong) NSMenuItem *menuItem; 16 | @property (nonatomic, strong) CPPreferencesToolbarDelegate *toolbarDelegate; 17 | 18 | - (void)installPlugin:(CPCodePilotPlugin *)plugin; 19 | 20 | - (void)installKeyBinding; 21 | - (void)installMenuItem; 22 | 23 | - (void)preferencesDidChange; 24 | 25 | - (IDEKeyBinding *)currentUserCPKeyBinding; 26 | - (void)keyBindingsHaveChanged:(NSNotification *)notification; 27 | - (void)installNotificationListeners; 28 | - (void)removeNotificationListeners; 29 | - (void)setupKeyBindingsIfNeeded; 30 | - (NSString *)keyBindingFromUserDefaults; 31 | - (IDEKeyboardShortcut *)keyboardShortcutFromUserDefaults; 32 | - (void)saveKeyBindingToUserDefaults:(NSString *)keyBinding forKey:(NSString *)defaultsKey; 33 | - (void)updateMenuItem:(NSMenuItem *)menuItem withShortcut:(IDEKeyboardShortcut *)keyboardShortcut; 34 | - (void)installPreferencePaneInToolbar:(NSToolbar *)toolbar; 35 | 36 | - (void)installStandardKeyBinding; 37 | - (IDEKeyBinding *)menuKeyBindingWithItemTitle:(NSString *)itemTitle underMenuCalled:(NSString *)menuName; 38 | - (void)updateKeyBinding:(IDEKeyBinding *)keyBinding forMenuItem:(NSMenuItem *)_menuItem defaultsKey:(NSString *)defaultsKey; 39 | @end -------------------------------------------------------------------------------- /Classes/MCStringScoring.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCStringScoring.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/27/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | 10 | struct MCStringScoringMatchTreeNode { 11 | struct MCStringScoringMatchTreeNode* parentNode; 12 | int matchIndex; 13 | unsigned int nextNodesCount; 14 | struct MCStringScoringMatchTreeNode** nextNodes; 15 | }; 16 | 17 | float MCStringScoring_scoreForCombination(int *combination, int combinationLength, int fullStringLength); 18 | float MCStringScoring_scoreStringForQuery(const char *scoredString, const char *query, int *indexesOfMatchedChars); 19 | float MCStringScoring_findBestMatch(int **matchIndexes, int queryLength, int valueLength, int* scoredIndexes); 20 | float MCStringScoring_scoreStringForQueryNEW(const char *scoredString, const char *query, int *indexesOfMatchedChars); 21 | float MCStringScoring_findBestMatchNEW(int **matchIndexes, int queryLength, int valueLength, int* scoredIndexes); 22 | void MCStringScoring_printMatches(int **matchIndexes, int queryLength, int valueLength); 23 | void MCStringScoring_printMatchTree(struct MCStringScoringMatchTreeNode *parentNode, int currentLevel); 24 | unsigned int MCStringScoring_buildMatchTree(int **matchIndexes, struct MCStringScoringMatchTreeNode *parentNode, int currentLevel, int maxLevel, int maxLevelElements); 25 | void MCStringScoring_freeMatchTree(struct MCStringScoringMatchTreeNode *rootNode); 26 | void MCStringScoring_combinationsFromTree(struct MCStringScoringMatchTreeNode *parentNode, int currentLevel, int maxLevel, int elementsCount, int **combinations, int *currentCombinationIndex); 27 | 28 | struct MCStringScoringMatchTreeNode* newMatchTreeNode(); -------------------------------------------------------------------------------- /MCCommons/MCStringScoring.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCStringScoring.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/27/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | 10 | struct MCStringScoringMatchTreeNode { 11 | struct MCStringScoringMatchTreeNode *parentNode; 12 | int matchIndex; 13 | unsigned int nextNodesCount; 14 | struct MCStringScoringMatchTreeNode **nextNodes; 15 | }; 16 | 17 | float MCStringScoring_scoreForCombination(int *combination, int combinationLength, int fullStringLength); 18 | float MCStringScoring_scoreStringForQuery(const char *scoredString, const char *query, int *indexesOfMatchedChars); 19 | float MCStringScoring_findBestMatch(int **matchIndexes, int queryLength, int valueLength, int *scoredIndexes); 20 | float MCStringScoring_scoreStringForQueryNEW(const char *scoredString, const char *query, int *indexesOfMatchedChars); 21 | float MCStringScoring_findBestMatchNEW(int **matchIndexes, int queryLength, int valueLength, int *scoredIndexes); 22 | void MCStringScoring_printMatches(int **matchIndexes, int queryLength, int valueLength); 23 | void MCStringScoring_printMatchTree(struct MCStringScoringMatchTreeNode *parentNode, int currentLevel); 24 | unsigned int MCStringScoring_buildMatchTree(int **matchIndexes, struct MCStringScoringMatchTreeNode *parentNode, int currentLevel, int maxLevel, int maxLevelElements); 25 | void MCStringScoring_freeMatchTree(struct MCStringScoringMatchTreeNode *rootNode); 26 | void MCStringScoring_combinationsFromTree(struct MCStringScoringMatchTreeNode *parentNode, int currentLevel, int maxLevel, int elementsCount, int **combinations, int *currentCombinationIndex); 27 | 28 | struct MCStringScoringMatchTreeNode *newMatchTreeNode(); -------------------------------------------------------------------------------- /CodePilot.xcodeproj/project.xcworkspace/xcshareddata/CodePilot.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 0732B84C-C0E7-4A00-98C8-1AEFB507C593 9 | IDESourceControlProjectName 10 | CodePilot 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | F5EA100B3BB7F4C8E2D01AE0EBB04FDBBF0AA304 14 | https://github.com/macoscope/CodePilot.git 15 | 16 | IDESourceControlProjectPath 17 | CodePilot.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | F5EA100B3BB7F4C8E2D01AE0EBB04FDBBF0AA304 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/macoscope/CodePilot.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | F5EA100B3BB7F4C8E2D01AE0EBB04FDBBF0AA304 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | F5EA100B3BB7F4C8E2D01AE0EBB04FDBBF0AA304 36 | IDESourceControlWCCName 37 | CodePilot 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Classes/NSView+RoundedFrame.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+RoundedFrame.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/23/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "NSView+RoundedFrame.h" 10 | 11 | @implementation NSView (RoundedFrame) 12 | + (void)drawRoundedFrame:(NSRect)roundedFrame withRadius:(NSInteger)radius filledWithColor:(NSColor *)color 13 | { 14 | [color set]; 15 | 16 | [[NSBezierPath bezierPathWithRoundedRect:NSMakeRect(roundedFrame.origin.x, roundedFrame.size.height - radius, radius, radius) 17 | xRadius:radius 18 | yRadius:radius] fill]; 19 | 20 | [[NSBezierPath bezierPathWithRoundedRect:NSMakeRect(roundedFrame.origin.x + roundedFrame.size.width - radius, roundedFrame.size.height - radius, radius, radius) 21 | xRadius:radius 22 | yRadius:radius] fill]; 23 | 24 | 25 | [[NSBezierPath bezierPathWithRoundedRect:NSMakeRect(roundedFrame.origin.x, roundedFrame.origin.y, radius, radius) 26 | xRadius:radius 27 | yRadius:radius] fill]; 28 | 29 | [[NSBezierPath bezierPathWithRoundedRect:NSMakeRect(roundedFrame.origin.x + roundedFrame.size.width - radius, roundedFrame.origin.y, radius, radius) 30 | xRadius:radius 31 | yRadius:radius] fill]; 32 | 33 | NSRectFill(NSMakeRect(roundedFrame.origin.x, roundedFrame.origin.y + radius / 2, roundedFrame.size.width, roundedFrame.size.height - radius)); 34 | 35 | NSRectFill(NSMakeRect(roundedFrame.origin.x + radius / 2, roundedFrame.size.height - radius, roundedFrame.size.width - radius, radius)); 36 | 37 | NSRectFill(NSMakeRect(roundedFrame.origin.x + radius / 2, roundedFrame.origin.y, roundedFrame.size.width - radius, radius)); 38 | } 39 | @end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | What is Code Pilot? 2 | =================== 3 | 4 | Read the [full story](http://macoscope.com/blog/the-story-of-code-pilot/) of Code Pilot. 5 | 6 | Code Pilot is a plugin for Xcode 5 & 6 that allows you to quickly find files, methods and symbols within your project without the need for your mouse. 7 | It uses fuzzy query matching to compute a list of results sorted by their relevancy. With just a few keystrokes you can jump to the method you're looking for. 8 | 9 | ![CodePilot Window](https://github.com/macoscope/CodePilot/raw/master/Screenshots/CodePilot_01.png "CodePilot Window") 10 | 11 | More about original Code Pilot release [here](http://codepilot.cc/). 12 | 13 | How to install Code Pilot? 14 | ========================== 15 | 16 | ##Alcatraz 17 | 18 | You can install Code Pilot using [Alcatraz](http://alcatraz.io) package manager 19 | 20 | ##Manual 21 | 22 | To use Code Pilot you have to build the project. It will automatically place `CodePilot3.xcplugin` file to your plugin directory - `~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins`. 23 | To load the plugin you have to restart Xcode. 24 | 25 | When the plugin is loaded you can open the CodePilot window with CMD + SHIFT + X, and then type your query. 26 | 27 | License 28 | ======= 29 | 30 | Copyright 2014 Macoscope Sp. z o.o. 31 | 32 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 33 | 34 | http://www.apache.org/licenses/LICENSE-2.0 35 | 36 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 37 | -------------------------------------------------------------------------------- /Classes/QSBSmallScroller.h: -------------------------------------------------------------------------------- 1 | // 2 | // QSBSmallScroller.h 3 | // 4 | // Copyright (c) 2007-2008 Google Inc. All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | // 32 | 33 | #import 34 | 35 | // A small iPhone style scroller 36 | @interface QSBSmallScroller : NSScroller 37 | @end 38 | -------------------------------------------------------------------------------- /Classes/NSWorkspace+OpenFileOnLine.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSWorkspace+OpenFileOnLine.m 3 | // CodePilot 4 | // 5 | // Created by Fjölnir Ásgeirsson on 2/2/14. 6 | // Copyright (c) 2014 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "NSWorkspace+OpenFileOnLine.h" 10 | 11 | NSString *kSublimeText2Identifier = @"com.sublimetext.2"; 12 | NSString *kSublimeText3Identifier = @"com.sublimetext.3"; 13 | NSString *kMacVimIdentifier = @"org.vim.MacVim"; 14 | NSString *kTextmateIdentifier = @"com.macromates.textmate"; 15 | NSString *kTextmate2Identifier = @"com.macromates.textmate.preview"; 16 | NSString *kBBEditIdentifier = @"com.barebones.bbedit"; 17 | 18 | 19 | @implementation NSWorkspace (OpenFileOnLine) 20 | 21 | + (NSString *)cp_schemeForEditor:(NSString *)editor 22 | { 23 | if ([editor isEqualToString:kSublimeText2Identifier] || 24 | [editor isEqualToString:kSublimeText3Identifier]) { 25 | return @"subl"; 26 | } 27 | if ([editor isEqualToString:kMacVimIdentifier]) { 28 | return @"mvim"; 29 | } 30 | if ([editor isEqualToString:kTextmateIdentifier]) { 31 | return @"txmt"; 32 | } 33 | if ([editor isEqualToString:kBBEditIdentifier]) { 34 | return @"txmt"; 35 | } 36 | else { 37 | return nil; 38 | } 39 | } 40 | 41 | - (void)cp_openURL:(NSURL *)url onLine:(NSUInteger)line 42 | { 43 | NSURL *editorURL = [self URLForApplicationToOpenURL:url]; 44 | NSString *editorIdentifier = [[NSBundle bundleWithURL:editorURL] bundleIdentifier]; 45 | NSString *scheme = [[self class] cp_schemeForEditor:editorIdentifier]; 46 | 47 | if (scheme) { 48 | url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://open?url=%@&line=%lu", 49 | scheme, 50 | [[url absoluteString] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 51 | (unsigned long)line]]; 52 | } 53 | [self openURL:url]; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Installer/build_installer_pkg.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "`dirname \"$0\"`" 4 | SCRIPT_WD=`pwd` 5 | 6 | PRODUCT_NAME="CodePilot3" 7 | PACKAGEMAKER_PATH="/Applications/PackageMaker.app" 8 | 9 | if [ ! -d "$PACKAGEMAKER_PATH" ]; then 10 | echo "Could not locate PackageMaker.app. You can download it from https://developer.apple.com/downloads (Auxiliary tools for Xcode)" 11 | exit 1 12 | fi 13 | 14 | if [ -z "$PROJECT_DIR" ]; then 15 | # Script invoked outside of Xcode, figure out environmental vars for ourself. 16 | PROJECT_DIR='..' 17 | BUILT_PRODUCTS_DIR="$PROJECT_DIR/build/Release" 18 | CONFIGURATION='Release' 19 | BUILT_PLUGIN="$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.xcplugin" 20 | PRODUCT_VERSION=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$BUILT_PLUGIN/Contents/Info.plist"` 21 | else 22 | PRODUCT_VERSION=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$PROJECT_DIR/Resources/Info.plist"` 23 | fi 24 | 25 | if [ "$CONFIGURATION" != "Release" ]; then 26 | echo "Could not generate package." 27 | echo "Active Configuration needs to be set to 'Release'." 28 | exit 1 29 | fi 30 | 31 | MY_INSTALLER_ROOT="$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.dst" 32 | BUILT_PLUGIN="$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.xcplugin" 33 | VERSIONED_NAME="$PRODUCT_NAME-$PRODUCT_VERSION" 34 | BUILT_PKG="$BUILT_PRODUCTS_DIR/$VERSIONED_NAME.pkg" 35 | 36 | # Delete old files if they're around. 37 | if [ -d "$MY_INSTALLER_ROOT" ]; then 38 | rm -rf "$MY_INSTALLER_ROOT" 39 | fi 40 | 41 | if [ -d "$BUILT_PKG" ]; then 42 | rm -rf "$BUILT_PKG" 43 | fi 44 | 45 | # Create the .pkg. 46 | mkdir "$MY_INSTALLER_ROOT" 47 | cp -R "$BUILT_PLUGIN" "$MY_INSTALLER_ROOT" 48 | 49 | "$PACKAGEMAKER_PATH/Contents/MacOS/PackageMaker" \ 50 | --root "$MY_INSTALLER_ROOT" \ 51 | --info "Info.plist" \ 52 | --resources resources \ 53 | --scripts scripts \ 54 | --target 10.4 \ 55 | --version "$PRODUCT_VERSION" \ 56 | --verbose \ 57 | --out "$BUILT_PKG" 58 | 59 | echo Package ready: 60 | ls -dl "$BUILT_PKG" 61 | du -hs "$BUILT_PKG" 62 | rm -rf "$MY_INSTALLER_ROOT" 63 | 64 | 65 | cd "`dirname $BUILT_PKG`" 66 | zip -r "$VERSIONED_NAME.zip" "$VERSIONED_NAME.pkg" 67 | 68 | echo ZIP file ready: 69 | ls -l "$VERSIONED_NAME.zip" 70 | 71 | -------------------------------------------------------------------------------- /Classes/CPResultTableViewColumn.m: -------------------------------------------------------------------------------- 1 | // 2 | // ResultTableViewColumn.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/15/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPResultTableViewColumn.h" 10 | #import "CPResultTableView.h" 11 | #import "CPSymbolCell.h" 12 | #import "CPFileReferenceCell.h" 13 | #import "CPFileReference.h" 14 | #import "CPCodePilotConfig.h" 15 | #import "CPSymbol.h" 16 | 17 | @implementation CPResultTableViewColumn 18 | - (id)init 19 | { 20 | self = [super init]; 21 | 22 | if (self) { 23 | [self setMaxWidth:WINDOW_WIDTH]; 24 | [self setMinWidth:WINDOW_WIDTH]; 25 | [self setWidth:WINDOW_WIDTH]; 26 | } 27 | 28 | return self; 29 | } 30 | 31 | - (id)dataCellForRow:(NSInteger)rowIndex 32 | { 33 | CPResultTableView *resultTableView = (CPResultTableView *)[self tableView]; 34 | 35 | if (nil == self.symbolCell) { 36 | self.symbolCell = [CPSymbolCell new]; 37 | } 38 | 39 | if (nil == self.fileCell) { 40 | self.fileCell = [CPFileReferenceCell new]; 41 | } 42 | 43 | self.fileCell.extendedDisplay = resultTableView.extendedDisplay; 44 | self.symbolCell.extendedDisplay = resultTableView.extendedDisplay; 45 | self.fileCell.query = resultTableView.fileQuery; 46 | self.symbolCell.query = resultTableView.symbolQuery; 47 | 48 | if ([resultTableView dataSource]) { 49 | id dataSource = [resultTableView dataSource]; 50 | if ([dataSource respondsToSelector:@selector(tableView:objectValueForTableColumn:row:)]) { 51 | id object = [dataSource tableView:resultTableView objectValueForTableColumn:self row:rowIndex]; 52 | if ([object isKindOfClass:[CPFileReference class]]) { 53 | return self.fileCell; 54 | } else if ([object isKindOfClass:[CPSymbol class]]) { 55 | return self.symbolCell; 56 | } else if (nil == object) { 57 | // happens rarely when we're reloading while user browses the table 58 | // it's caused by timer-based, async communication and searching 59 | // user won't see it probably anyway 60 | LOG(@"WARNING: nil object requested cell at index %d", rowIndex); 61 | return self.symbolCell; 62 | } else { 63 | LOG(@"WARNING: object of unknown class found %@ at index %d", object, rowIndex); 64 | } 65 | } 66 | } 67 | 68 | return [super dataCellForRow:rowIndex]; 69 | } 70 | @end 71 | -------------------------------------------------------------------------------- /Classes/CPResultTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ResultTableView.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/14/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPResultTableView.h" 10 | #import "CPCodePilotConfig.h" 11 | #import "CPSearchWindowView.h" 12 | #import "CPResultTableViewColumn.h" 13 | 14 | @implementation CPResultTableView 15 | - (id)initWithFrame:(NSRect)frameRect 16 | { 17 | self = [super initWithFrame:frameRect]; 18 | 19 | if (self) { 20 | self.extendedDisplay = NO; 21 | self.fileQuery = @""; 22 | self.symbolQuery = @""; 23 | 24 | CPResultTableViewColumn *tableColumn = [CPResultTableViewColumn new]; 25 | [self addTableColumn:tableColumn]; 26 | 27 | [self setHeaderView:nil]; 28 | [self setAllowsColumnReordering:NO]; 29 | [self setAllowsColumnResizing:NO]; 30 | [self setAllowsColumnSelection:NO]; 31 | [self setAllowsMultipleSelection:NO]; 32 | [self setAllowsEmptySelection:NO]; 33 | [self setAllowsTypeSelect:NO]; 34 | [self setAlphaValue:1]; 35 | [self setBackgroundColor:[NSColor clearColor]]; 36 | [self setGridColor:[NSColor clearColor]]; 37 | [self setIntercellSpacing:NSZeroSize]; 38 | } 39 | 40 | return self; 41 | } 42 | 43 | - (void)highlightSelectionInClipRect:(NSRect)clipRect 44 | { 45 | NSInteger selectedRow = [self selectedRow]; 46 | 47 | if (selectedRow >= 0) { 48 | NSRect selectedRowRect = [self rectOfRow:selectedRow]; 49 | if (NSIntersectsRect(selectedRowRect, clipRect)) { 50 | [TABLE_ROW_HIGHLIGHT_COLOR set]; 51 | 52 | NSRectFill(selectedRowRect); 53 | } 54 | } 55 | } 56 | 57 | - (void)reloadData 58 | { 59 | [super reloadData]; 60 | } 61 | 62 | - (BOOL)isOpaque 63 | { 64 | return NO; 65 | } 66 | 67 | - (void)keyDown:(NSEvent *)theEvent 68 | { 69 | } 70 | 71 | - (void)mouseDown:(NSEvent *)theEvent 72 | { 73 | } 74 | 75 | - (BOOL)canBecomeKeyView 76 | { 77 | return NO; 78 | } 79 | 80 | - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent 81 | { 82 | return NO; 83 | } 84 | 85 | - (BOOL)acceptsFirstResponder 86 | { 87 | return NO; 88 | } 89 | 90 | - (NSUInteger)requiredHeight 91 | { 92 | NSUInteger newTableViewHeight = 0; 93 | NSUInteger rowCount = [self.dataSource numberOfRowsInTableView:self]; 94 | NSTableColumn *firstColumn = [[self tableColumns] objectAtIndex:0]; 95 | 96 | for (NSInteger i = 0; i < rowCount; i++) { 97 | newTableViewHeight += [[firstColumn dataCellForRow:i] requiredHeight]; 98 | } 99 | 100 | return MIN(newTableViewHeight, MAX_TABLE_HEIGHT); 101 | } 102 | @end 103 | -------------------------------------------------------------------------------- /Classes/CPInfoWindowView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPInfoWindowView.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/11/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPInfoWindowView.h" 10 | #import "CPCodePilotConfig.h" 11 | #import "CPStatusLabel.h" 12 | #import "NSAttributedString+Hyperlink.h" 13 | #import 14 | 15 | @implementation CPInfoWindowView 16 | - (id)initWithFrame:(NSRect)frame 17 | { 18 | self = [super initWithFrame:frame]; 19 | 20 | if (self) { 21 | self.cornerRadius = CORNER_RADIUS; 22 | self.backgroundColor = BACKGROUND_COLOR; 23 | 24 | [self setupInfoLabel]; 25 | } 26 | 27 | return self; 28 | } 29 | 30 | - (void)setupInfoLabel 31 | { 32 | CGFloat infoLabelfontSize = [NSFont systemFontSize] + 2; 33 | 34 | self.infoLabel = [[CPStatusLabel alloc] initWithFrame:NSMakeRect(WINDOW_MARGIN, 35 | WINDOW_MARGIN, 36 | INFO_WINDOW_WIDTH / 2.0 - (WINDOW_MARGIN * 2) + 10, 37 | INFO_WINDOW_HEIGHT - (WINDOW_MARGIN * 2))]; 38 | 39 | [self.infoLabel setFont:[[NSFontManager sharedFontManager] convertFont:[NSFont systemFontOfSize:infoLabelfontSize] toHaveTrait:NSBoldFontMask]]; 40 | [self.infoLabel setTextColor:[NSColor whiteColor]]; 41 | 42 | [self addSubview:self.infoLabel]; 43 | } 44 | 45 | - (void)drawProductLogo 46 | { 47 | NSBundle *myBundle = [NSBundle bundleForClass:[self class]]; 48 | NSString *iconPath = [myBundle pathForResource:@"CodePilotIcon" ofType:@"icns"]; 49 | NSImage *icon = [[NSImage alloc] initWithContentsOfFile:iconPath]; 50 | 51 | NSRect dstRect = {INFO_WINDOW_WIDTH / 2.0 + WINDOW_MARGIN + 10, 0, 128, 128}; 52 | NSRect srcRect = {0, 0, [icon size]}; 53 | 54 | [icon drawInRect:dstRect 55 | fromRect:srcRect 56 | operation:NSCompositeSourceOver 57 | fraction:1.0f]; 58 | } 59 | 60 | - (void)drawRect:(NSRect)rect 61 | { 62 | [super drawRect:rect]; 63 | 64 | [self drawProductLogo]; 65 | } 66 | 67 | - (NSSize)windowFrameRequirements 68 | { 69 | return NSMakeSize(INFO_WINDOW_WIDTH, INFO_WINDOW_HEIGHT); 70 | } 71 | 72 | - (BOOL)acceptsFirstResponder 73 | { 74 | return YES; 75 | } 76 | 77 | - (void)keyDown:(NSEvent *)theEvent 78 | { 79 | if (kVK_Escape == [theEvent keyCode]) { 80 | [PILOT_WINDOW_DELEGATE hideWindow]; 81 | } 82 | } 83 | 84 | - (void)mouseDown:(NSEvent *)theEvent 85 | { 86 | if (nil != self.clickUrl) { 87 | [[NSWorkspace sharedWorkspace] openURL:self.clickUrl]; 88 | } else { 89 | [super mouseDown:theEvent]; 90 | } 91 | } 92 | @end 93 | -------------------------------------------------------------------------------- /MCCommons/MCLog.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCLog.h 3 | // Macoscope Commons Library 4 | // 5 | // Created by Daniel on 08-11-03. 6 | // Copyright 2008 Macosope. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MCLog : NSObject 12 | + (void)file:(char *)sourceFile function:(char *)functionName lineNumber:(int)lineNumber format:(NSString *)format, ...; 13 | + (NSString *)messageWithFile:(char *)sourceFile function:(char *)functionName lineNumber:(int)lineNumber format:(NSString *)format, ...; 14 | + (void)prefix:(NSString *)prefixString format:(NSString *)format, ...; 15 | @end 16 | 17 | 18 | #define LOG(s,...) [MCLog file:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:(s),##__VA_ARGS__] 19 | #define LOGCALL [MCLog file:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:@"%s", _cmd] 20 | 21 | #define LOG_if (condition, s, ...) \ 22 | do { \ 23 | if ( (condition) ) { \ 24 | [MCLog file:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:(s),##__VA_ARGS__]; \ 25 | } \ 26 | } while (0) 27 | 28 | #define WARN_if (condition, s, ...) \ 29 | do { \ 30 | if ( (condition) ) { \ 31 | [MCLog file:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:(s),##__VA_ARGS__]; \ 32 | } \ 33 | } while (0) 34 | 35 | #define WARN(s,...) [MCLog file:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:(s),##__VA_ARGS__] 36 | #define ERROR(s,...) [MCLog file:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:(s),##__VA_ARGS__] 37 | 38 | // cos a'la log ale zwracajace message zamiast wrzucac go do logow - przydatne jako domyslny komunikat w assercjach 39 | #define LOGMSG(s,...) [MCLog messageWithFile:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:(s),##__VA_ARGS__] 40 | #define FAILMSG [MCLog messageWithFile:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:@"Assertion failed."] 41 | 42 | 43 | 44 | // Based on http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/ 45 | NSString * MCToStringFromTypeAndValue(const char * typeCode, void * value); 46 | #define MCNSStringWithFormat(FORMAT, ARGS... ) [NSString stringWithFormat: (FORMAT), ARGS] 47 | // mnemo - [F]or[M]atted [S]tring 48 | #define _fms(FORMAT, ARGS... ) [NSString stringWithFormat: (FORMAT), ARGS] 49 | 50 | #define _2NS(_X_) ({__typeof__(_X_) _Y_ = (_X_); MCToStringFromTypeAndValue(@encode(__typeof__(_X_)), &_Y_);}) 51 | #define LOGVAR(_X_) {__typeof__(_X_) _Y_ = (_X_); [MCLog file:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:@"?%s = `%@'", # _X_, MCToStringFromTypeAndValue(@encode(__typeof__(_X_)), &_Y_)];} 52 | -------------------------------------------------------------------------------- /Classes/CPSymbolCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPSymbolCache.m 3 | // CodePilot 4 | // 5 | // Created by karol on 5/11/12. 6 | // Copyright (c) 2012 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPSymbolCache.h" 10 | #import "CPSymbol.h" 11 | #import "CPXcodeInterfaces.h" 12 | 13 | @interface CPSymbolCache () 14 | @property (nonatomic, strong) NSMutableDictionary *symbolsForFilePath; 15 | @end 16 | 17 | @implementation CPSymbolCache 18 | + (CPSymbolCache *)sharedInstance 19 | { 20 | static CPSymbolCache *symbolCacheSharedInstance; 21 | static dispatch_once_t predicate; 22 | dispatch_once(&predicate, ^{ 23 | symbolCacheSharedInstance = [[CPSymbolCache alloc] init]; 24 | }); 25 | 26 | return symbolCacheSharedInstance; 27 | } 28 | 29 | - (id)init 30 | { 31 | self = [super init]; 32 | 33 | if (self) { 34 | self.symbolsForFilePath = [[NSMutableDictionary alloc] init]; 35 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onFileChangeNotification:) name:IDEEditorDocumentDidChangeNotification object:nil]; 36 | } 37 | 38 | return self; 39 | } 40 | 41 | - (void)onFileChangeNotification:(NSNotification *)notification 42 | { 43 | /* 44 | Be careful with [IDESourceCodeDocument class], use NSClassFromString(@"IDESourceCodeDocument") instead. 45 | The reason is IDESourceCodeDocument is a private class residing in some dylib loaded after launching Xcode. However, 46 | since Xcode 6.3.2 plugins are loaded before loading the dylib with IDESourceCodeDocument, and so linker freaks out. 47 | NSClassFromString(@"IDESourceCodeDocument"), though not perfect, is safer because will return nil until appropriate 48 | dylib is loaded. 49 | */ 50 | if (![[notification object] isKindOfClass:NSClassFromString(@"IDESourceCodeDocument")]) { 51 | return; 52 | } 53 | 54 | IDESourceCodeDocument *document = [notification object]; 55 | 56 | for (Xcode3FileReference *fileReference in (NSArray *)[document knownFileReferences]) { 57 | [self.symbolsForFilePath removeObjectForKey:[[fileReference resolvedFilePath] pathString]]; 58 | } 59 | } 60 | 61 | - (CPSymbol *)symbolForIDEIndexSymbol:(IDEIndexSymbol *)ideIndexSymbol relatedFilePath:(NSString *)relatedFilePath 62 | { 63 | if (relatedFilePath == nil) { 64 | relatedFilePath = @""; 65 | } 66 | 67 | if (nil == self.symbolsForFilePath[relatedFilePath]) { 68 | self.symbolsForFilePath[relatedFilePath] = [NSMutableDictionary dictionary]; 69 | } 70 | 71 | NSNumber *symbolHash = @([ideIndexSymbol hash]); 72 | NSMutableDictionary *symbols = self.symbolsForFilePath[relatedFilePath]; 73 | 74 | if (nil == symbols[symbolHash]) { 75 | symbols[symbolHash] = [[CPSymbol alloc] initWithIDEIndexSymbol:ideIndexSymbol forRelatedFileAtPath:relatedFilePath]; 76 | } 77 | 78 | return symbols[symbolHash]; 79 | } 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /Classes/CPSearchWindowView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPSearchWindowView.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/14/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPHUDViewWithRoundCorners.h" 11 | #import "CPCodePilotConfig.h" 12 | 13 | #define WINDOW_INFO_LABEL_TOPMARGIN 6.0f 14 | #define WINDOW_INFO_LABEL_HEIGHT 21.0f 15 | #define WINDOW_SEARCHFIELD_TOPMARGIN 7.0f 16 | #define WINDOW_SEARCHFIELD_HEIGHT 28.0f 17 | #define WINDOW_SEARCHFIELD_LEFT_MARGIN 27.0f 18 | #define WINDOW_UPPER_STATUS_LABEL_TOPMARGIN 25.0f 19 | #define WINDOW_UPPER_STATUS_LABEL_HEIGHT 19.0f 20 | #define WINDOW_TABLEVIEW_TOPMARGIN 4.0f 21 | #define WINDOW_LOWER_STATUS_LABEL_TOPMARGIN 8.0f 22 | #define WINDOW_LOWER_STATUS_LABEL_HEIGHT 19.0f 23 | #define WINDOW_CONTENT_BOTTOMMARGIN 6.0f 24 | 25 | 26 | @class CPResultTableView, CPSearchField, CPStatusLabel; 27 | 28 | @interface CPSearchWindowView : CPHUDViewWithRoundCorners 29 | @property (nonatomic, strong) CPSearchField *searchField; 30 | @property (nonatomic, strong) CPStatusLabel *infoStatusLabel; 31 | @property (nonatomic, strong) CPStatusLabel *upperStatusLabel; 32 | @property (nonatomic, strong) CPStatusLabel *lowerStatusLabel; 33 | @property (nonatomic, strong) CPResultTableView *resultTableView; 34 | @property (nonatomic, strong) NSScrollView *resultTableScrollView; 35 | @property (nonatomic, strong) NSControl *indexingProgressIndicator; 36 | @property (nonatomic, assign) NSUInteger currentMainContentViewHeight; 37 | @property (nonatomic, strong) NSImageRep *headerImageRepresentation; 38 | @property (nonatomic, strong) NSImageRep *headerWithInfoImageRepresentation; 39 | @property (nonatomic, strong) NSImageRep *footerImageRepresentation; 40 | @property (nonatomic, strong) NSImageRep *infoLabelBarImageRepresentation; 41 | @property (nonatomic, assign) BOOL documentationViewOn; 42 | 43 | - (NSSize)windowFrameRequirements; 44 | - (void)layoutSubviews; 45 | - (void)setupIndexingProgressIndicator; 46 | - (void)setupResultTableScrollViewAndResultTableView; 47 | - (void)setupUpperStatusLabel; 48 | - (void)setupLowerStatusLabel; 49 | - (void)setupSearchField; 50 | - (void)setupResultTableView; 51 | - (void)setupInfoLabel; 52 | - (BOOL)_infoLabelPresent; 53 | - (NSInteger)mainContentViewHeight; 54 | - (void)removeOrAddToSubviewsBasedOnVisibilityOfView:(NSView *)view; 55 | - (void)alignIndexingProgressIndicator; 56 | - (void)alignLowerStatusLabel; 57 | - (void)alignUpperStatusLabel; 58 | - (void)alignScrollViewFrame; 59 | - (void)alignSearchField; 60 | - (void)alignInfoStatusLabel; 61 | 62 | - (void)loadUIElements; 63 | - (void)loadFooterImageRepresentation; 64 | - (void)loadHeaderImageRepresentation; 65 | - (void)loadInfoLabelBarImageRepresentation; 66 | - (void)drawHeader; 67 | - (void)drawFooter; 68 | - (void)drawInfoLabelBar; 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Classes/CPSelectedObjectCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SelectedObjectCell.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/28/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPSelectedObjectCell.h" 10 | #import "CPCodePilotConfig.h" 11 | #import "NSView+RoundedFrame.h" 12 | 13 | @implementation CPSelectedObjectCell 14 | - (id)init 15 | { 16 | self = [super init]; 17 | 18 | if (self) { 19 | self.stringAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys: 20 | [NSFont fontWithName:SEARCHFIELD_TOKEN_FONT 21 | size:SEARCHFIELD_TOKEN_FONT_SIZE], NSFontAttributeName, 22 | [NSColor clearColor], NSBackgroundColorAttributeName, 23 | SEARCHFIELD_TOKEN_FONT_COLOR, NSForegroundColorAttributeName, nil]; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 30 | { 31 | } 32 | 33 | - (NSRect)cellFrameForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(NSRect)lineFrag glyphPosition:(NSPoint)position characterIndex:(NSUInteger)charIndex 34 | { 35 | NSSize sizeForString = [[self title] sizeWithAttributes:self.stringAttributes]; 36 | 37 | return NSMakeRect(0, 0, sizeForString.width + SEARCHFIELD_TOKEN_INSIDE_MARGIN*2, sizeForString.height); 38 | } 39 | 40 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView characterIndex:(NSUInteger)charIndex layoutManager:(NSLayoutManager *)layoutManager 41 | { 42 | [NSView drawRoundedFrame:cellFrame 43 | withRadius:6 44 | filledWithColor:SEARCHFIELD_TOKEN_BACKGROUND_COLOR]; 45 | 46 | cellFrame.origin.x += SEARCHFIELD_TOKEN_INSIDE_MARGIN; 47 | 48 | [[self title] drawInRect:cellFrame withAttributes:self.stringAttributes]; 49 | } 50 | 51 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)aView characterIndex:(NSUInteger)charIndex 52 | { 53 | } 54 | 55 | - (void)highlight:(BOOL)flag withFrame:(NSRect)cellFrame inView:(NSView *)aView 56 | { 57 | } 58 | 59 | - (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)aTextView atCharacterIndex:(NSUInteger)charIndex untilMouseUp:(BOOL)flag 60 | { 61 | return NO; 62 | } 63 | 64 | - (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)aTextView untilMouseUp:(BOOL)flag 65 | { 66 | return NO; 67 | } 68 | 69 | - (BOOL)wantsToTrackMouse 70 | { 71 | return NO; 72 | } 73 | 74 | - (BOOL)wantsToTrackMouseForEvent:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView atCharacterIndex:(NSUInteger)charIndex 75 | { 76 | return NO; 77 | } 78 | 79 | - (NSCellType)type 80 | { 81 | return NSTextCellType; 82 | } 83 | 84 | - (NSImage *)image 85 | { 86 | return nil; 87 | } 88 | 89 | - (BOOL)importsGraphics 90 | { 91 | return YES; 92 | } 93 | @end 94 | -------------------------------------------------------------------------------- /Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 4A287b 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | CodePilot3 11 | CFBundleIdentifier 12 | net.macoscope.CodePilot3 13 | CFBundleInfoDictionaryVersion 14 | 3.0 15 | CFBundleName 16 | CodePilot3 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 3.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 3.0 25 | DTCompiler 26 | com.apple.compilers.llvm.clang.1_0 27 | DTPlatformBuild 28 | 29 | DTPlatformVersion 30 | GM 31 | DTSDKBuild 32 | 4A287b 33 | DTSDKName 34 | 35 | DTXcode 36 | 0400 37 | DTXcodeBuild 38 | 39 | DVTPlugInCompatibilityUUIDs 40 | 41 | ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C 42 | F41BD31E-2683-44B8-AE7F-5F09E919790E 43 | 7265231C-39B4-402C-89E1-16167C4CC990 44 | 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 45 | 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 46 | E969541F-E6F9-4D25-8158-72DC3545A6C6 47 | 9F75337B-21B4-4ADC-B558-F9CADF7073A7 48 | A16FF353-8441-459E-A50C-B071F53F51B7 49 | C4A681B0-4A26-480E-93EC-1218098B9AA0 50 | A2E4D43F-41F4-4FB9-BB94-7177011C9AED 51 | AABB7188-E14E-4433-AD3B-5CD791EAD9A3 52 | CC0D0F4F-05B3-431A-8F33-F84AFCB2C651 53 | FEC992CC-CA4A-4CFD-8881-77300FCB848A 54 | AD68E85B-441B-4301-B564-A45E4919A6AD 55 | 992275C1-432A-4CF7-B659-D84ED6D42D3F 56 | 640F884E-CE55-4B40-87C0-8869546CAB7A 57 | 63FC1C47-140D-42B0-BB4D-A10B2D225574 58 | 37B30044-3B14-46BA-ABAA-F01000C27B63 59 | 8DC44374-2B35-4C57-A6FE-2AD66A36AAD9 60 | 61 | NSPrincipalClass 62 | CPCodePilotPlugin 63 | SUEnableAutomaticChecks 64 | YES 65 | SUFeedURL 66 | http://updates.macoscope.net/feed/codepilot2beta 67 | SUPublicDSAKeyFile 68 | dsa_pub.pem 69 | SUShowReleaseNotes 70 | YES 71 | XC4Compatible 72 | 73 | XCGCReady 74 | YES 75 | XCPluginHasUI 76 | NO 77 | 78 | 79 | -------------------------------------------------------------------------------- /Classes/CPSearchController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SearchController.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/9/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPCodePilotConfig.h" 11 | 12 | @class CPXcodeWrapper, CPResultTableView, CPSearchField, CPStatusLabel, CPResult; 13 | 14 | enum { 15 | DataModeRecentJumps = 1, 16 | DataModeMatchingFiles = 2, 17 | DataModeMatchingSymbols = 3 18 | 19 | } DataMode; 20 | 21 | @interface CPSearchController : NSObject 22 | @property (nonatomic, weak) NSTimer *indexingProgressIndicatorTimer; 23 | @property (nonatomic, weak) NSControl *indexingProgressIndicator; 24 | @property (nonatomic, weak) CPSearchField *searchField; 25 | @property (nonatomic, weak) CPResultTableView *tableView; 26 | @property (nonatomic, weak) CPStatusLabel *upperStatusLabel; 27 | @property (nonatomic, weak) CPStatusLabel *lowerStatusLabel; 28 | @property (nonatomic, weak) CPStatusLabel *infoStatusLabel; 29 | @property (nonatomic, strong) CPXcodeWrapper *xcodeWrapper; 30 | @property (nonatomic, strong) NSArray *suggestedObjects; 31 | @property (nonatomic, assign) NSUInteger currentDataMode; 32 | @property (nonatomic, strong) CPResult *selectedElement; 33 | 34 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView; 35 | - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex; 36 | - (void)selectRowAtIndex:(NSUInteger)rowIndex; 37 | - (void)windowDidBecomeActive; 38 | - (void)updateContentsWithSearchField; 39 | - (void)setupRecentJumpsData; 40 | - (void)setupMatchingFilesAndSymbolsData; 41 | - (void)setupMatchingSymbolsData; 42 | - (void)setupStatusLabels; 43 | - (void)setupRecentJumpsStatusLabels; 44 | - (void)setupMatchingFilesStatusLabels; 45 | - (void)setupMatchingSymbolsStatusLabels; 46 | - (NSDictionary *)upperStatusLabelStringAttributes; 47 | - (NSDictionary *)lowerStatusLabelStringAttributes; 48 | - (void)setupLowerStatusLabelForMatchingFiles; 49 | - (NSMutableAttributedString *)boldFacedStatusLabelString:(NSString *)str; 50 | - (void)windowDidBecomeInactive; 51 | - (void)windowWillBecomeActive; 52 | - (void)saveSelectedElement; 53 | - (void)updateSelectionAfterDataChange; 54 | #ifdef PRESERVE_SELECTION 55 | - (NSInteger)indexOfObjectIsSuggestedCurrentlyForObject:(id)object; 56 | #endif 57 | - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row; 58 | - (BOOL)spacePressedForSearchField:(CPSearchField *)searchField; 59 | - (void)animateIndexingProgressIndicator:(NSTimer *)aTimer; 60 | - (void)setupIndexingProgressIndicatorTimer; 61 | - (void)noteQueriesChanged; 62 | - (void)noteProjectIndexChanged; 63 | - (void)setupInfoStatusLabel; 64 | - (NSDictionary *)infoStatusLabelUnregisteredStringAttributes; 65 | - (NSDictionary *)infoStatusLabelNextVersionAvailableStringAttributes; 66 | - (void)setupTooMuchResultsStatusLabels; 67 | 68 | - (NSFont *)statusLabelFont; 69 | - (NSMutableAttributedString *)normalFacedStatusLabelString:(NSString *)str; 70 | @end -------------------------------------------------------------------------------- /CodePilot.xcodeproj/xcshareddata/xcschemes/CodePilot.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | 61 | 67 | 68 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Classes/CPCodePilotWindowDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPCodePilotWindowDelegate.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/9/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPCodePilotWindowDelegate.h" 10 | #import "CPXcodeWrapper.h" 11 | #import "CPSearchController.h" 12 | #import "CPResultTableView.h" 13 | #import "CPWindow.h" 14 | #import "CPSearchWindowView.h" 15 | #import "CPCodePilotConfig.h" 16 | #import "CPStatusLabel.h" 17 | #import "CPSearchField.h" 18 | #import "CPSearchFieldTextView.h" 19 | 20 | @implementation CPCodePilotWindowDelegate 21 | - (id)initWithXcodeWrapper:(CPXcodeWrapper *)xcodeWrapper 22 | { 23 | self = [super init]; 24 | 25 | if (self) { 26 | self.ourWindowIsOpen = NO; 27 | 28 | self.searchController = [CPSearchController new]; 29 | [self.searchController setXcodeWrapper:xcodeWrapper]; 30 | 31 | self.window = [[CPWindow alloc] initWithDefaultSettings]; 32 | [self.window setDelegate:self]; 33 | 34 | [self.searchController setSearchField:[self.window.searchWindowView searchField]]; 35 | [[self.window.searchWindowView searchField] setDelegate:self.searchController]; 36 | 37 | [self.searchController setIndexingProgressIndicator:[self.window.searchWindowView indexingProgressIndicator]]; 38 | [self.searchController setUpperStatusLabel:[self.window.searchWindowView upperStatusLabel]]; 39 | [self.searchController setLowerStatusLabel:[self.window.searchWindowView lowerStatusLabel]]; 40 | [self.searchController setInfoStatusLabel:[self.window.searchWindowView infoStatusLabel]]; 41 | 42 | [self.searchController setTableView:[self.window.searchWindowView resultTableView]]; 43 | [[self.window.searchWindowView resultTableView] setDataSource:self.searchController]; 44 | [[self.window.searchWindowView resultTableView] setDelegate:self.searchController]; 45 | } 46 | 47 | return self; 48 | } 49 | 50 | - (void)openFirstRunWindow 51 | { 52 | [self.window firstRunOrderFront]; 53 | [self.window makeKeyWindow]; 54 | self.ourWindowIsOpen = YES; 55 | } 56 | 57 | - (void)openWindow 58 | { 59 | if (self.ourWindowIsOpen) { 60 | return; 61 | } 62 | 63 | [self.searchController windowWillBecomeActive]; 64 | [self.window orderFront:self]; 65 | [self.window makeKeyWindow]; 66 | [self.searchController windowDidBecomeActive]; 67 | self.ourWindowIsOpen = YES; 68 | } 69 | 70 | - (void)hideWindow 71 | { 72 | [self.window orderOut:self]; 73 | self.ourWindowIsOpen = NO; 74 | } 75 | 76 | // we need custom field editor in order to work with search field the way we want 77 | - (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject 78 | { 79 | if ([anObject isKindOfClass:[CPSearchField class]]) { 80 | if (!self.searchFieldTextEditor) { 81 | self.searchFieldTextEditor = [[CPSearchFieldTextView alloc] init]; 82 | [self.searchFieldTextEditor setFieldEditor:YES]; 83 | } 84 | return self.searchFieldTextEditor; 85 | } 86 | return nil; 87 | } 88 | 89 | - (void)windowDidResignKey:(NSNotification *)notification 90 | { 91 | [self hideWindow]; 92 | } 93 | 94 | - (void)windowDidResignMain:(NSNotification *)notification 95 | { 96 | } 97 | 98 | - (void)windowWillClose:(NSNotification *)notification 99 | { 100 | } 101 | @end -------------------------------------------------------------------------------- /Classes/CPCodePilotPlugin.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPCodePilotPlugin.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/18/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPCodePilotPlugin.h" 10 | #import "CPCodePilotWindowDelegate.h" 11 | #import "CPXcodeWrapper.h" 12 | #import "CPPluginInstaller.h" 13 | 14 | #include 15 | 16 | @implementation CPCodePilotPlugin 17 | + (void)pluginDidLoad:(id)arg1 18 | { 19 | } 20 | 21 | + (void)load 22 | { 23 | // Avoid instantiating plugin if no Xcode is launched. 24 | // Loading the plugin from xcodebuild command caused a crash because the plugin tries to load a window for itself 25 | NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"]; 26 | if ([currentApplicationName isEqual:@"Xcode"]) { 27 | LOG(@"CODE PILOT: CURRENT_XCODE_VERSION: %@ CURRENT_XCODE_REVISION: %@", CURRENT_XCODE_VERSION, CURRENT_XCODE_REVISION); 28 | // just instantiate the singleton 29 | (void)[CPCodePilotPlugin sharedInstance]; 30 | } 31 | } 32 | 33 | - (id)init 34 | { 35 | self = [super init]; 36 | 37 | if (self) { 38 | self.isUserLevelDebugOn = [[NSUserDefaults standardUserDefaults] boolForKey:DEFAULTS_USER_LEVEL_DEBUG_KEY]; 39 | 40 | [self checkForFirstRun]; 41 | 42 | self.xcWrapper = [CPXcodeWrapper new]; 43 | self.windowDelegate = [[CPCodePilotWindowDelegate alloc] initWithXcodeWrapper:self.xcWrapper]; 44 | 45 | // we want to start real installation once the app is fully launched 46 | [[NSNotificationCenter defaultCenter] addObserver:self 47 | selector:@selector(applicationDidFinishLaunching:) 48 | name:NSApplicationDidFinishLaunchingNotification 49 | object:nil]; 50 | LOG(@"%@ %@ Plugin loaded.", PRODUCT_NAME, PRODUCT_CURRENT_VERSION); 51 | } 52 | 53 | return self; 54 | } 55 | 56 | - (void)applicationDidFinishLaunching:(NSNotification *)notification 57 | { 58 | self.installer = [[CPPluginInstaller alloc] init]; 59 | 60 | [self.installer installPlugin:self]; 61 | 62 | if (self.firstRunEver) { 63 | [self.windowDelegate openFirstRunWindow]; 64 | } 65 | } 66 | 67 | - (void)openCodePilotWindow 68 | { 69 | LOGCALL; 70 | 71 | if (self.windowDelegate.ourWindowIsOpen) { 72 | [self.windowDelegate hideWindow]; 73 | } 74 | 75 | [self.xcWrapper reloadXcodeState]; 76 | [self.windowDelegate openWindow]; 77 | } 78 | 79 | - (void)checkForFirstRun 80 | { 81 | self.thisVersionFirstRun = YES; 82 | self.firstRunEver = YES; 83 | 84 | NSString *lastVersionId = [[NSUserDefaults standardUserDefaults] objectForKey:DEFAULTS_LAST_VERSION_RUN_KEY]; 85 | if (!IsEmpty(lastVersionId)) { 86 | self.firstRunEver = NO; 87 | if ([lastVersionId isEqualToString:PRODUCT_CURRENT_VERSION]) { 88 | self.thisVersionFirstRun = NO; 89 | } 90 | } 91 | 92 | [[NSUserDefaults standardUserDefaults] setObject:PRODUCT_CURRENT_VERSION forKey:DEFAULTS_LAST_VERSION_RUN_KEY]; 93 | } 94 | 95 | + (instancetype)sharedInstance 96 | { 97 | static id sharedInstance; 98 | static dispatch_once_t onceToken; 99 | 100 | dispatch_once(&onceToken, ^{ 101 | sharedInstance = [[CPCodePilotPlugin alloc] init]; 102 | }); 103 | 104 | return sharedInstance; 105 | } 106 | @end 107 | -------------------------------------------------------------------------------- /Classes/CPXcodeWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // CPXcodeWrapper.h 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/9/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CPCodePilotConfig.h" 11 | 12 | @class CPFileReference, CPSymbol, CPWorkspaceSymbolCache, CPResult; 13 | 14 | @interface CPXcodeWrapper : NSObject 15 | @property (nonatomic, strong) NSMutableArray *currentlyIndexedWorkspaces; 16 | @property (nonatomic, strong) NSMutableArray *workspaceSymbolCaches; 17 | @property (nonatomic, assign) BOOL symbolCachingInProgress; 18 | 19 | - (void)reloadAfterPreferencesChange; 20 | - (void)reloadXcodeState; 21 | - (BOOL)hasOpenWorkspace; 22 | - (NSScreen *)currentScreen; 23 | - (BOOL)currentProjectIsIndexing; 24 | - (void)openFileOrSymbol:(id)fileOrSymbol; 25 | - (void)openFileOrSymbol:(id)fileOrSymbol inExternalEditor:(BOOL)aUseExternal; 26 | - (void)openCPSymbol:(CPSymbol *)symbol; 27 | - (void)openCPSymbol:(CPSymbol *)symbol inExternalEditor:(BOOL)aUseExternal; 28 | - (void)openCPFileReference:(CPFileReference *)cpFileReference; 29 | - (void)openCPFileReference:(CPFileReference *)cpFileReference inExternalEditor:(BOOL)aUseExternal; 30 | - (NSString *)currentProjectName; 31 | - (NSString *)normalizedQueryForQuery:(NSString *)query; 32 | - (NSArray *)contentsForQuery:(NSString *)query fromResult:(CPResult *)result; 33 | - (NSArray *)filesAndSymbolsFromProjectForQuery:(NSString *)query; 34 | - (NSArray *)recentlyVisited; 35 | - (NSString *)currentSelectionSymbolString; 36 | + (NSArray *)symbolsForProject:(id)pbxProject; 37 | - (NSArray *)cpFileReferencesMatchingQuery:(NSString *)query; 38 | - (NSArray *)topLevelCPSymbolsMatchingQuery:(NSString *)query; 39 | - (NSArray *)arrayOfCPFileReferencesByWrappingXcodeFileReferences:(NSArray *)xcodeFileReferences; 40 | - (id)pbxFileReferenceForCPFileReference:(CPFileReference *)cpFileReference; 41 | - (NSArray *)cpSymbolsFromFile:(CPFileReference *)fileObject matchingQuery:(NSString *)query; 42 | - (NSArray *)arrayOfCPSymbolsByWrappingIDESymbols:(NSArray *)ideSymbols forCPFileReference:(CPFileReference *)fileObject; 43 | 44 | - (NSArray *)recursiveChildrenOfPBXGroup:(PBXGroup *)pbxGroup; 45 | - (NSArray *)flattenedProjectContents; 46 | - (IDEWorkspace *)currentWorkspace; 47 | - (IDEIndex *)currentIndex; 48 | - (NSArray *)recursiveChildrenOfIDEIndexSymbol:(IDEIndexSymbol *)ideIndexSymbol; 49 | - (NSArray *)allIDEIndexSymbolsFromCPFileReference:(CPFileReference *)fileReference; 50 | - (IDEEditorContext *)currentEditorContext; 51 | - (IDEWorkspaceDocument *)currentWorkspaceDocument; 52 | - (NSArray *)arrayOfCPFileReferencesByWrappingFileURLs:(NSArray *)fileURLs; 53 | - (IDEWorkspaceWindowController *)currentWorkspaceWindowController; 54 | 55 | - (NSArray *)arrayOfCPFileReferencesByWrappingDVTFilePaths:(NSArray *)dvtFilePaths; 56 | 57 | - (void)willIndexWorkspace:(NSNotification *)notification; 58 | - (void)didIndexWorkspace:(NSNotification *)notification; 59 | - (void)removeClosedWorkspacesFromCurrentlyIndexed; 60 | - (NSArray *)allOpenedWorkspaces; 61 | - (IDEWorkspace *)workspaceForIndex:(IDEIndex *)index; 62 | 63 | - (void)updateWorkspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace; 64 | - (CPWorkspaceSymbolCache *)workspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace; 65 | 66 | - (void)updateWorkspaceSymbolCacheForWorkspace:(IDEWorkspace *)workspace withWorkspaceSymbolCache:(CPWorkspaceSymbolCache *)workspaceSymbolCache; 67 | - (BOOL)isSymbolCachingInProgress; 68 | 69 | - (NSArray *)recentlyVisitedFiles; 70 | @end -------------------------------------------------------------------------------- /Classes/QSBSmallScroller.m: -------------------------------------------------------------------------------- 1 | // 2 | // QSSmallScroller.m 3 | // 4 | // Copyright (c) 2007-2008 Google Inc. All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | // 32 | 33 | #import "QSBSmallScroller.h" 34 | 35 | @implementation QSBSmallScroller 36 | 37 | // Set the width to 0 so our scrollers don't limit the size of the content area 38 | + (CGFloat)scrollerWidth { 39 | return 0; 40 | } 41 | 42 | - (void)drawKnob { 43 | 44 | NSRect knobRect = NSInsetRect([self rectForPart:NSScrollerKnob], 2, 0); 45 | 46 | CGFloat propFraction = 1.0 - pow([self knobProportion], 10); 47 | // Restrict color by proportion 48 | // Almost complete scroll bars are nearly translucent 49 | 50 | CGFloat heightFraction = MAX(1.0 - (NSHeight(knobRect) / 128), 0.333); 51 | // Restrict color by height 52 | // Tall scrollbars are dimmer 53 | 54 | CGFloat alphaFraction = propFraction * heightFraction; 55 | 56 | NSColor *knobColor = [NSColor colorWithDeviceWhite:0.75 alpha:alphaFraction]; 57 | [knobColor set]; 58 | knobRect = NSInsetRect(knobRect, 3.0, 0.0); 59 | CGFloat width = NSWidth(knobRect) * 0.5; 60 | NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:knobRect 61 | xRadius:width 62 | yRadius:width]; 63 | [path fill]; 64 | } 65 | 66 | - (NSUsableScrollerParts)usableParts { 67 | return NSNoScrollerParts; 68 | } 69 | 70 | // Don't draw arrows 71 | - (void)drawArrow:(NSScrollerArrow)whichArrow highlight:(BOOL)flag { 72 | } 73 | 74 | - (BOOL)isOpaque { 75 | return NO; 76 | } 77 | 78 | // Don't draw normal scroller parts 79 | - (void)drawParts { 80 | } 81 | 82 | - (void)drawRect:(NSRect)rect { 83 | NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; 84 | CGContextRef cgContext = (CGContextRef)([currentContext graphicsPort]); 85 | CGContextSetAlpha(cgContext, 0.75); 86 | CGContextBeginTransparencyLayer(cgContext, 0); 87 | [self drawKnob]; 88 | CGContextEndTransparencyLayer(cgContext); 89 | } 90 | @end 91 | -------------------------------------------------------------------------------- /Classes/NSString+Abbreviation.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Abbreviation.m 3 | // Quark 4 | // 5 | // Created by Daniel on 09-12-04. 6 | // Copyright 2009 Macosope. All rights reserved. 7 | // 8 | 9 | #import "NSString+Abbreviation.h" 10 | #import "MCStringScoring.h" 11 | #import "MCCommons.h" 12 | 13 | // based on NSString_BLTRExtensions.h/m from quicksilver codebase 14 | @implementation NSString (Abbreviation) 15 | - (NSArray *)hitsForString:(NSString *)queryString 16 | { 17 | const char *scoredString = [self cStringUsingEncoding:NSUTF8StringEncoding]; 18 | const char *cQuery = [[queryString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] cStringUsingEncoding:NSUTF8StringEncoding]; 19 | 20 | NSMutableArray *hitsArray = [NSMutableArray arrayWithCapacity:[self length]]; 21 | int *indexesOfMatchedChars; 22 | int cQueryLength = strlen(cQuery); 23 | float finalScore; 24 | 25 | if (cQueryLength > 0) { 26 | int index; 27 | indexesOfMatchedChars = malloc(sizeof(int)*strlen(cQuery)); 28 | memset(indexesOfMatchedChars, -1, sizeof(int)*strlen(cQuery)); 29 | 30 | finalScore = MCStringScoring_scoreStringForQuery(scoredString, cQuery, indexesOfMatchedChars); 31 | 32 | if (-1.0 != finalScore) { 33 | for (index=0;index 0) { 60 | indexesOfMatchedChars = malloc(sizeof(int)*strlen(cQuery)); 61 | memset(indexesOfMatchedChars, -1, sizeof(int)*strlen(cQuery)); 62 | 63 | finalScore = MCStringScoring_scoreStringForQueryNEW(scoredString, cQuery, indexesOfMatchedChars); 64 | free(indexesOfMatchedChars); 65 | } 66 | 67 | if (-1.0 != finalScore) { 68 | return [NSNumber numberWithFloat:finalScore]; 69 | } else { 70 | return nil; 71 | } 72 | } 73 | 74 | 75 | // fast, without scoring 76 | - (BOOL)matchesFuzzyQuery:(NSString *)query 77 | { 78 | NSString *comparedValue = self; 79 | int queryIndex = 0; 80 | int valueIndex = 0; 81 | int queryLength = [query length]; 82 | int valueLength = [comparedValue length]; 83 | BOOL wordMatches = YES; 84 | 85 | for (; queryIndex < queryLength; queryIndex++) { 86 | unichar queryChar = [query characterAtIndex:queryIndex]; 87 | BOOL charFound = NO; 88 | for (; valueIndex < valueLength; valueIndex++) { 89 | unichar valueChar = [comparedValue characterAtIndex:valueIndex]; 90 | // lowercase matches uppercase too. uppercase matches just uppercase. 91 | if (queryChar == valueChar || 92 | (islower(queryChar) && toupper(queryChar) == valueChar) 93 | ) { 94 | charFound = YES; 95 | break; 96 | } 97 | } 98 | 99 | if (!charFound) { 100 | wordMatches = NO; 101 | break; 102 | } 103 | 104 | valueIndex++; 105 | } 106 | 107 | return wordMatches; 108 | } 109 | @end -------------------------------------------------------------------------------- /Classes/CPSearchFieldTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SearchFieldTextView.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/27/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPSearchFieldTextView.h" 10 | #import "CPCodePilotConfig.h" 11 | #import "CPSearchField.h" 12 | 13 | static const CGSize TextContainerInset = (NSSize){5, 0}; 14 | enum { 15 | BackspaceCharacter = '\x7f', 16 | SpaceCharacter = ' ' 17 | }; 18 | 19 | @implementation CPSearchFieldTextView 20 | - (id)init 21 | { 22 | self = [super init]; 23 | 24 | if (self) { 25 | [self setContinuousSpellCheckingEnabled:NO]; 26 | [self setUsesFontPanel:NO]; 27 | [self setRichText:NO]; 28 | [self setInsertionPointColor:SEARCHFIELD_FONT_COLOR]; 29 | [self setTextContainerInset:TextContainerInset]; 30 | 31 | self.someKeyIsDown = NO; 32 | } 33 | 34 | return self; 35 | } 36 | 37 | - (void)keyDown:(NSEvent *)theEvent 38 | { 39 | // we record key as pressed unless it has cmd pressed with it as well. 40 | // cmd-backspace for example doesn't cause keyUp to be called later on, 41 | // so we're left with someKeyIsDown set for the true until the next KeyDown 42 | if (![theEvent modifierFlags] & NSCommandKeyMask) { 43 | self.someKeyIsDown = YES; 44 | } 45 | 46 | unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; 47 | 48 | switch (ch) { 49 | case BackspaceCharacter: 50 | if ([theEvent modifierFlags] & NSCommandKeyMask) { 51 | if ([[self delegate] respondsToSelector:@selector(cmdBackspaceKeyDown)] && [(id)[self delegate] cmdBackspaceKeyDown]) { 52 | return; 53 | } 54 | } 55 | break; 56 | 57 | case SpaceCharacter: 58 | if ([[self delegate] respondsToSelector:@selector(spaceKeyDown)] && [(id)[self delegate] spaceKeyDown]) { 59 | return; 60 | } 61 | break; 62 | } 63 | 64 | [super keyDown:theEvent]; 65 | 66 | // move the cursor to an end - the user is not allowed to move around freely. 67 | [super setSelectedRange:NSMakeRange([[self textStorage] length], 0)]; 68 | } 69 | 70 | - (void)keyUp:(NSEvent *)theEvent 71 | { 72 | self.someKeyIsDown = NO; 73 | [super keyUp:theEvent]; 74 | } 75 | 76 | // prevent selection just by moving the cursor to an end 77 | - (void)setSelectedRange:(NSRange)charRange affinity:(NSSelectionAffinity)affinity stillSelecting:(BOOL)flag 78 | { 79 | if ([[self textStorage] length] == charRange.location && 0 == charRange.length) { 80 | [super setSelectedRange:NSMakeRange([[self textStorage] length], 0) affinity:affinity stillSelecting:flag]; 81 | } 82 | } 83 | 84 | // pasting and dragging into are disabled 85 | - (NSArray *)readablePasteboardTypes 86 | { 87 | return [NSArray arrayWithObject:NSStringPboardType]; 88 | } 89 | 90 | // insertText with some data sanitization 91 | - (void)pasteString:(NSString *)str 92 | { 93 | // trim newlines and spaces at the end and remove all other newlines 94 | str = [str stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 95 | str = [str stringByReplacingOccurrencesOfString:@" " withString:@""]; 96 | 97 | [self insertText:str]; 98 | } 99 | 100 | - (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard type:(NSString *)type 101 | { 102 | NSString *stringToBePasted = [pboard stringForType:NSStringPboardType]; 103 | 104 | if (nil != stringToBePasted && stringToBePasted.length > 0) { 105 | [self pasteString:stringToBePasted]; 106 | return YES; 107 | } 108 | 109 | return NO; 110 | } 111 | 112 | // disable right-click menu 113 | - (NSMenu *)menuForEvent:(NSEvent *)theEvent 114 | { 115 | return nil; 116 | } 117 | @end -------------------------------------------------------------------------------- /Classes/NSAppleEventDescriptor+ToObject.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSAppleEventDescriptor+ToObject.m 3 | // Quark 4 | // 5 | // Created by Daniel on 09-10-15. 6 | // Copyright 2009 Macosope. All rights reserved. 7 | // 8 | 9 | #import "NSAppleEventDescriptor+ToObject.h" 10 | #import "CPCodePilotConfig.h" 11 | 12 | // TODO: brak obslugi ldt - 'ldt ' (LongDateTime) http://lists.apple.com/archives/applescript-implementors/2003/Mar/msg00019.html 13 | 14 | @interface NSAppleEventDescriptor (MCPrivate) 15 | - (id)_toDictionary; 16 | @end 17 | 18 | @implementation NSAppleEventDescriptor (ToObject) 19 | 20 | - (id)toObject 21 | { 22 | const AEDesc *aed = [self aeDesc]; 23 | DescType desc = aed->descriptorType; 24 | id ret = nil; 25 | switch (desc) { 26 | case typeAEList: 27 | ret = [NSMutableArray array]; 28 | unsigned int i = 1; // AS lists are 1-indexed. 29 | for (i=1; i <= [self numberOfItems]; i++) 30 | [ret addObject:[[self descriptorAtIndex:i] toObject]]; 31 | break; 32 | case typeAERecord: 33 | ret = [self _toDictionary]; 34 | break; 35 | case typeTrue: 36 | ret = [NSNumber numberWithBool:YES]; 37 | break; 38 | case typeFalse: 39 | ret = [NSNumber numberWithBool:NO]; 40 | break; 41 | case typeNull: 42 | ret = [NSNull null]; 43 | break; 44 | case typeChar: 45 | case 'utxt': 46 | ret = [self stringValue]; 47 | break; 48 | case 'long': 49 | case 'shor': 50 | ret = [NSNumber numberWithLong:[self int32Value]]; 51 | break; 52 | case 'doub': 53 | case 'sing': 54 | ret = [NSNumber numberWithDouble:[[self stringValue] doubleValue]]; 55 | break; 56 | case 'bool': 57 | ret = [NSNumber numberWithBool:[[self stringValue] boolValue]]; 58 | break; 59 | default: 60 | //http://lists.apple.com/archives/applescript-implementors/2003/Mar/msg00019.html 61 | LOG(@"Unknown AEType: '%C%C%C%C'", _cmd, desc >> 24 & 0xFF, desc >> 16 & 0xFF, desc >> 8 & 0xFF, desc & 0xFF); 62 | ret = [self stringValue]; 63 | } 64 | return ret; 65 | } 66 | 67 | - (id)_toDictionary 68 | { 69 | unsigned long i = 1; // AS lists are 1-indexed 70 | NSMutableDictionary *d = [NSMutableDictionary dictionary]; 71 | for (i=1; i <= [self numberOfItems]; i++) { 72 | AEKeyword keyword = [self keywordForDescriptorAtIndex:i]; 73 | if (keyword == 'usrf') { 74 | // 'usrf' records appear to be a list wherein the first item is the key and the second item is the object 75 | NSAppleEventDescriptor *list = [self paramDescriptorForKeyword:keyword]; 76 | unsigned long j = 1; // AS lists are 1-indexed 77 | while (j <= [list numberOfItems]) { 78 | NSString *key = [[list descriptorAtIndex:j++] toObject]; 79 | NSString *obj = [[list descriptorAtIndex:j++] toObject]; 80 | if (key && obj) [d setObject:obj forKey:key]; 81 | } 82 | } else { // These are the keys that are based on keywords. They can just be tossed in. 83 | NSString *key = nil; 84 | // This is a short list of Applescript keywords. If it's not in this list, then we use the 4 char code. 85 | switch (keyword) { 86 | case 'pnam': key = @"name"; break; 87 | case 'url ': key = @"url"; break; 88 | case 'kywd': key = @"keyword"; break; 89 | case 'pALL': key = @"properties"; break; 90 | case 'capp': key = @"application"; break; 91 | case 'cwin': key = @"window"; break; 92 | case 'cmnu': key = @"menu"; break; 93 | case 'TEXT': key = @"string"; break; 94 | case 'reco': key = @"record"; break; 95 | case 'nmbr': key = @"number"; break; 96 | default: 97 | key = [NSString stringWithFormat:@"%C%C%C%C", (unichar)(keyword >> 24 & 0xFF), (unichar)(keyword >> 16 & 0xFF), (unichar)(keyword >> 8 & 0xFF), (unichar)(keyword & 0xFF)]; 98 | LOG(@"Unknown applescript keyword: %@", key); 99 | } 100 | // If the keyword is 'usrf', then it's likely the non-keyword items of a record. Let's place them in the current dictionary. 101 | [d setObject:[[self paramDescriptorForKeyword:keyword] toObject] forKey:key]; 102 | } 103 | } 104 | return d; 105 | } 106 | 107 | @end 108 | 109 | -------------------------------------------------------------------------------- /Classes/CPWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // SearchWindow.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/14/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPWindow.h" 10 | #import "CPSearchWindowView.h" 11 | #import "CPCodePilotConfig.h" 12 | #import "CPNoProjectOpenWindowView.h" 13 | #import "CPXcodeVersionUnsupportedWindowView.h" 14 | #import "CPFirstRunWindowView.h" 15 | #import "CPXcodeWrapper.h" 16 | 17 | @implementation CPWindow 18 | - (id)initWithDefaultSettings 19 | { 20 | return [[CPWindow alloc] initWithContentRect:NSMakeRect(100, 100, WINDOW_WIDTH, 500) 21 | styleMask:NSTitledWindowMask 22 | backing:NSBackingStoreBuffered 23 | defer:0]; 24 | } 25 | 26 | - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag 27 | { 28 | self = [super initWithContentRect:contentRect 29 | styleMask:NSBorderlessWindowMask 30 | backing:bufferingType 31 | defer:flag]; 32 | 33 | if (self) { 34 | [self setBackgroundColor:[NSColor clearColor]]; 35 | [self setHasShadow:YES]; 36 | [self setOpaque:NO]; 37 | 38 | self.xcodeVersionUnsupportedWindowView = [[CPXcodeVersionUnsupportedWindowView alloc] initWithFrame:NSMakeRect(0, 0, self.frame.size.width, self.frame.size.height)]; 39 | self.noProjectOpenWindowView = [[CPNoProjectOpenWindowView alloc] initWithFrame:NSMakeRect(0, 0, self.frame.size.width, self.frame.size.height)]; 40 | self.searchWindowView = [[CPSearchWindowView alloc] initWithFrame:NSMakeRect(0, 0, self.frame.size.width, self.frame.size.height)]; 41 | self.firstRunWindowView = [[CPFirstRunWindowView alloc] initWithFrame:NSMakeRect(0, 0, self.frame.size.width, self.frame.size.height)]; 42 | 43 | [self setCollectionBehavior:NSWindowCollectionBehaviorMoveToActiveSpace]; 44 | } 45 | 46 | return self; 47 | } 48 | 49 | - (void)firstRunOrderFront 50 | { 51 | [self setContentView:self.firstRunWindowView]; 52 | [self updateFrameWithViewRequirements]; 53 | [self makeFirstResponder:[self contentView]]; 54 | [super orderFront:self]; 55 | } 56 | 57 | - (void)orderFront:(id)sender 58 | { 59 | if (NO_PROJECT_IS_CURRENTLY_OPEN) { 60 | [self setContentView:self.noProjectOpenWindowView]; 61 | } else { 62 | [self setContentView:self.searchWindowView]; 63 | [self.searchWindowView layoutSubviews]; 64 | } 65 | 66 | [self updateFrameWithViewRequirements]; 67 | [self makeFirstResponder:[self contentView]]; 68 | [super orderFront:sender]; 69 | } 70 | 71 | - (NSScreen *)destinationScreen 72 | { 73 | NSScreen *xCodeCurrentScreen = [[[CPCodePilotPlugin sharedInstance] xcWrapper] currentScreen]; 74 | 75 | return xCodeCurrentScreen ?: [NSScreen mainScreen]; 76 | } 77 | 78 | - (void)updateFrameWithViewRequirements 79 | { 80 | [self updateFrameWithViewRequirementsWithAnimation:NO]; 81 | } 82 | 83 | - (void)updateFrameWithViewRequirementsWithAnimation:(BOOL)animation 84 | { 85 | NSSize viewWindowSizeRequirements = [self.contentView windowFrameRequirements]; 86 | 87 | CGFloat newXorigin = [self destinationScreen].frame.origin.x + ([self destinationScreen].frame.size.width - viewWindowSizeRequirements.width) / 2.0; 88 | CGFloat newYorigin = [self destinationScreen].frame.origin.y + (([self destinationScreen].frame.size.height * (1 - WINDOW_TOP_LOCATION_ON_THE_SCREEN)) - 89 | viewWindowSizeRequirements.height); 90 | 91 | NSRect newWindowFrame = NSMakeRect(newXorigin, 92 | newYorigin, 93 | viewWindowSizeRequirements.width, 94 | viewWindowSizeRequirements.height); 95 | 96 | [self setFrame:newWindowFrame display:YES animate:animation]; 97 | } 98 | 99 | // Normally windows with the NSBorderlessWindowMask can't become the key window 100 | - (BOOL)canBecomeKeyWindow 101 | { 102 | return YES; 103 | } 104 | @end 105 | -------------------------------------------------------------------------------- /MCCommons/MCLog.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCLog.m 3 | // Macoscope Commons Library 4 | // 5 | // Created by Daniel on 08-11-03. 6 | // Copyright 2008 Macosope. All rights reserved. 7 | // 8 | 9 | #import "MCLog.h" 10 | #import "CPCodePilotConfig.h" 11 | 12 | @implementation MCLog 13 | + (void)prefix:(NSString *)prefixString format:(NSString *)format, ... 14 | { 15 | @autoreleasepool { 16 | va_list ap; 17 | NSString *message; 18 | va_start(ap,format); 19 | 20 | message = [[NSString alloc] initWithFormat:format arguments:ap]; 21 | va_end(ap); 22 | 23 | NSLog(@"%@ %@", prefixString, message); 24 | 25 | } 26 | } 27 | 28 | + (void)file:(char *)sourceFile function:(char *)functionName lineNumber:(int)lineNumber format:(NSString *)format, ... 29 | { 30 | @autoreleasepool { 31 | va_list ap; 32 | NSString *print, *file, *function; 33 | va_start(ap,format); 34 | 35 | file = [[NSString alloc] initWithBytes:sourceFile length:strlen(sourceFile) encoding:NSUTF8StringEncoding]; 36 | 37 | 38 | function = [NSString stringWithCString:functionName encoding:NSASCIIStringEncoding]; 39 | print = [[NSString alloc] initWithFormat:format arguments:ap]; 40 | va_end(ap); 41 | 42 | NSString *fileLocation = [file lastPathComponent]; 43 | 44 | NSLog(@"%@:%d %@; %@", fileLocation, lineNumber, function, print); 45 | 46 | } 47 | } 48 | + (NSString *)messageWithFile:(char *)sourceFile function:(char *)functionName lineNumber:(int)lineNumber format:(NSString *)format, ... 49 | { 50 | @autoreleasepool { 51 | va_list ap; 52 | NSString *print, *file, *function; 53 | va_start(ap,format); 54 | file = [[NSString alloc] initWithBytes:sourceFile length:strlen(sourceFile) encoding:NSUTF8StringEncoding]; 55 | 56 | function = [NSString stringWithCString:functionName encoding:NSASCIIStringEncoding]; 57 | print = [[NSString alloc] initWithFormat:format arguments:ap]; 58 | va_end(ap); 59 | NSString * buffer = [NSString stringWithFormat:@"%@:%d %@; %@", [file lastPathComponent], lineNumber, function, print]; 60 | return buffer; 61 | } 62 | } 63 | 64 | NSString * MCToStringFromTypeAndValue(const char * typeCode, void * value) 65 | { 66 | if (strcmp(typeCode, @encode(NSPoint)) == 0) { 67 | return NSStringFromPoint(*(NSPoint *)value); 68 | 69 | } else if (strcmp(typeCode, @encode(NSSize)) == 0) { 70 | return NSStringFromSize(*(NSSize *)value); 71 | 72 | } else if (strcmp(typeCode, @encode(NSRect)) == 0) { 73 | return NSStringFromRect(*(NSRect *)value); 74 | 75 | } else if (strcmp(typeCode, @encode(Class)) == 0) { 76 | return NSStringFromClass(*(Class *)value); 77 | 78 | } else if (strcmp(typeCode, @encode(SEL)) == 0) { 79 | return NSStringFromSelector(*(SEL *)value); 80 | 81 | } else if (strcmp(typeCode, @encode(NSRange)) == 0) { 82 | return NSStringFromRange(*(NSRange *)value); 83 | 84 | } else if (strcmp(typeCode, @encode(id)) == 0) { 85 | return MCNSStringWithFormat(@"%@", (__bridge id)(value)); 86 | } else if (strcmp(typeCode, @encode(BOOL)) == 0) { 87 | return (*(BOOL *)value) ? @"YES" : @"NO"; 88 | } else if (strcmp(typeCode, @encode(int)) == 0) { 89 | return MCNSStringWithFormat(@"%d", *(int *)value); 90 | 91 | } else if (strcmp(typeCode, @encode(NSUInteger)) == 0) { 92 | return MCNSStringWithFormat(@"%lu", *(NSUInteger *)value); 93 | 94 | } else if (strcmp(typeCode, @encode(unichar)) == 0) { 95 | return MCNSStringWithFormat(@"%d", *(unichar *)value); 96 | 97 | } else if (strcmp(typeCode, @encode(CGFloat)) == 0) { 98 | return MCNSStringWithFormat(@"%f", *(CGFloat *)value); 99 | 100 | } else if (strcmp(typeCode, @encode(CGPoint)) == 0) { 101 | return NSStringFromPoint(NSPointFromCGPoint(*(CGPoint *)value)); 102 | 103 | } else if (strcmp(typeCode, @encode(CGRect)) == 0) { 104 | return NSStringFromRect(NSRectFromCGRect(*(CGRect *)value)); 105 | 106 | } else if (strcmp(typeCode, @encode(CGSize)) == 0) { 107 | return NSStringFromSize(NSSizeFromCGSize(*(CGSize *)value)); 108 | } 109 | 110 | return MCNSStringWithFormat(@"? <%s>", typeCode); 111 | } 112 | 113 | @end -------------------------------------------------------------------------------- /Classes/CPResultCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ResultCell.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/2/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPResultCell.h" 10 | #import "CPCodePilotConfig.h" 11 | 12 | @implementation CPResultCell 13 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 14 | { 15 | NSInteger rowIndex = [(NSTableView *)controlView rowAtPoint:NSMakePoint(cellFrame.origin.x, cellFrame.origin.y)]; 16 | 17 | NSString *backgroundImageFileName; 18 | 19 | if ([self isHighlighted]) { 20 | backgroundImageFileName = @"ResultSelection"; 21 | } else { 22 | if (rowIndex % 2) { 23 | backgroundImageFileName = @"DarkCell"; 24 | } else { 25 | backgroundImageFileName = @"LightCell"; 26 | } 27 | } 28 | 29 | [self drawWithBackgroundImageNamed:backgroundImageFileName withFrame:cellFrame]; 30 | } 31 | 32 | - (void)drawWithBackgroundImageNamed:(NSString *)backgroundImageName withFrame:(NSRect)cellFrame 33 | { 34 | NSString *imagePath = [[NSBundle bundleForClass:[self class]] pathForResource:backgroundImageName 35 | ofType:@"png"]; 36 | 37 | NSImage *image = [[NSImage alloc] initWithContentsOfFile:imagePath]; 38 | 39 | NSImageRep *imageRep = [[image representations] objectAtIndex:0]; 40 | 41 | [imageRep drawInRect:cellFrame 42 | fromRect:NSMakeRect(0, 0, imageRep.size.width, imageRep.size.height) 43 | operation:NSCompositeSourceOver 44 | fraction:1.0 45 | respectFlipped:YES 46 | hints:nil]; 47 | } 48 | 49 | - (NSParagraphStyle *)defaultParagraphStyle 50 | { 51 | NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 52 | [paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; 53 | [paragraphStyle setAlignment:NSLeftTextAlignment]; 54 | return paragraphStyle; 55 | } 56 | 57 | // what extra attributes does a character need when it's hit with a query 58 | - (NSDictionary *)characterHitExtraAttributes 59 | { 60 | return [[NSDictionary alloc] initWithObjectsAndKeys: 61 | [NSNumber numberWithInt:NSUnderlineStyleThick], NSUnderlineStyleAttributeName, nil]; 62 | } 63 | 64 | // sourceString with hit attributes added in all the right places 65 | - (NSAttributedString *)queryHitAttributedStringWithString:(NSString *)subjectString 66 | { 67 | NSMutableAttributedString *attributedSubjectString = [[NSMutableAttributedString alloc] initWithString:subjectString]; 68 | 69 | if (!IsEmpty(self.query)) { 70 | NSArray *hitsArray = [subjectString hitsForString:self.query]; 71 | for (NSNumber *characterIndexOnHit in hitsArray) { 72 | [attributedSubjectString addAttributes:[self characterHitExtraAttributes] 73 | range:NSMakeRange([characterIndexOnHit unsignedIntValue], 1)]; 74 | } 75 | } 76 | 77 | return attributedSubjectString; 78 | } 79 | 80 | - (NSDictionary *)defaultStringAttributes 81 | { 82 | return [NSDictionary dictionaryWithObjectsAndKeys: [NSColor clearColor], NSBackgroundColorAttributeName, 83 | [self defaultParagraphStyle], NSParagraphStyleAttributeName, nil]; 84 | } 85 | 86 | - (void)drawIconImage:(NSImage *)icon withFrame:(NSRect)cellFrame 87 | { 88 | if (icon) { 89 | NSRect availableRect; // rect (part of cellFrame), available for drawing 90 | NSRect srcRect, dstRect; // dstRect is the actual rect where image from srcrect lands 91 | 92 | srcRect.origin = NSZeroPoint; 93 | srcRect.size = [icon size]; 94 | 95 | availableRect = NSMakeRect(cellFrame.origin.x + RESULT_CELL_ICON_LEFT_MARGIN, 96 | cellFrame.origin.y + 4, 97 | RESULT_CELL_FILE_ICON_WIDTH, 98 | cellFrame.size.height - 8); 99 | 100 | // TODO/FIXME: adjust origins to make it look good if aspect ratio is out of whack 101 | dstRect.origin.x = availableRect.origin.x; 102 | dstRect.origin.y = availableRect.origin.y; 103 | 104 | dstRect.size.height = availableRect.size.height; 105 | dstRect.size.width = srcRect.size.width / (srcRect.size.height / availableRect.size.height); 106 | 107 | [icon drawInRect:dstRect fromRect:srcRect operation:NSCompositeSourceOver fraction:1.0f respectFlipped:YES hints:nil]; 108 | } 109 | } 110 | @end -------------------------------------------------------------------------------- /Classes/CPFileReferenceCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FileSelectionCell.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/10/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPFileReferenceCell.h" 10 | #import "CPCodePilotConfig.h" 11 | #import "CPFileReference.h" 12 | 13 | @implementation CPFileReferenceCell 14 | @dynamic cpFileReference; 15 | 16 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 17 | { 18 | [super drawWithFrame:cellFrame inView:controlView]; 19 | 20 | [self drawIconWithFrame:cellFrame]; 21 | [self drawFileNameWithFrame:cellFrame]; 22 | 23 | if (self.extendedDisplay) { 24 | [self drawGroupNameWithFrame:cellFrame]; 25 | } 26 | } 27 | 28 | - (void)drawIconWithFrame:(NSRect)cellFrame 29 | { 30 | [self drawIconImage:[self.cpFileReference icon] withFrame:cellFrame]; 31 | } 32 | 33 | - (void)drawFileNameWithFrame:(NSRect)cellFrame 34 | { 35 | NSMutableDictionary *fileNameStringAttributes = [[self defaultStringAttributes] mutableCopy]; 36 | 37 | [fileNameStringAttributes setObject:[NSFont fontWithName:FILE_SELECTION_CELL_FONT_NAME 38 | size:FILE_SELECTION_CELL_FONT_SIZE] 39 | forKey:NSFontAttributeName]; 40 | 41 | if ([self isHighlighted]) { 42 | [fileNameStringAttributes setObject:FILE_SELECTION_CELL_HIGHLIGHTED_FONT_COLOR forKey:NSForegroundColorAttributeName]; 43 | } else { 44 | [fileNameStringAttributes setObject:FILE_SELECTION_CELL_FONT_COLOR forKey:NSForegroundColorAttributeName]; 45 | } 46 | 47 | NSMutableAttributedString *fileNameAttributedString = [[self queryHitAttributedStringWithString:[self.cpFileReference fileName]] mutableCopy]; 48 | 49 | [fileNameAttributedString addAttributes:fileNameStringAttributes range:NSMakeRange(0, [fileNameAttributedString length])]; 50 | 51 | // odstep miedzy ikona a nazwa pliku; 52 | CGFloat fileNameMargin; 53 | 54 | if (self.extendedDisplay) { 55 | fileNameMargin = RESULT_CELL_FILE_EXTENDED_ICON_WIDTH; 56 | } else { 57 | fileNameMargin = RESULT_CELL_FILE_ICON_WIDTH; 58 | } 59 | 60 | [fileNameAttributedString drawInRect:NSMakeRect(cellFrame.origin.x + fileNameMargin, 61 | cellFrame.origin.y + 4, 62 | cellFrame.size.width - fileNameMargin, 63 | cellFrame.size.height)]; 64 | } 65 | 66 | - (void)drawGroupNameWithFrame:(NSRect)cellFrame 67 | { 68 | if ([self.cpFileReference groupName]) { 69 | NSMutableDictionary *groupNameStringAttributes = [[self defaultStringAttributes] mutableCopy]; 70 | 71 | [groupNameStringAttributes setObject:[NSFont fontWithName:FILE_SELECTION_CELL_EXTENDED_INFO_FONT_NAME 72 | size:FILE_SELECTION_CELL_EXTENDED_INFO_FONT_SIZE] 73 | forKey:NSFontAttributeName]; 74 | 75 | if ([self isHighlighted]) { 76 | [groupNameStringAttributes setObject:FILE_SELECTION_CELL_HIGHLIGHTED_FONT_COLOR forKey:NSForegroundColorAttributeName]; 77 | } else { 78 | [groupNameStringAttributes setObject:FILE_SELECTION_CELL_FONT_COLOR forKey:NSForegroundColorAttributeName]; 79 | } 80 | 81 | NSString *groupNameString = [self.cpFileReference groupName]; 82 | NSString *projectName = [self.cpFileReference projectName]; 83 | 84 | if ([self.cpFileReference subprojectFile]) { 85 | groupNameString = [NSString stringWithFormat:@"%@ (%@)", groupNameString, projectName]; 86 | } 87 | 88 | NSAttributedString *groupNameAttributedString = [[NSAttributedString alloc] initWithString:groupNameString 89 | attributes:groupNameStringAttributes]; 90 | 91 | [groupNameAttributedString drawInRect:NSMakeRect(cellFrame.origin.x + RESULT_CELL_FILE_EXTENDED_ICON_WIDTH, 92 | cellFrame.origin.y + FILE_SELECTION_CELL_FONT_SIZE + 9, 93 | cellFrame.size.width - RESULT_CELL_FILE_EXTENDED_ICON_WIDTH, 94 | cellFrame.size.height - (FILE_SELECTION_CELL_FONT_SIZE + 9))]; 95 | } 96 | } 97 | 98 | - (CPFileReference *)cpFileReference 99 | { 100 | return (CPFileReference *)self.objectValue; 101 | } 102 | 103 | - (NSUInteger)requiredHeight 104 | { 105 | if (self.extendedDisplay) { 106 | return FILE_SELECTION_CELL_EXTENDED_HEIGHT; 107 | } else { 108 | return FILE_SELECTION_CELL_HEIGHT; 109 | } 110 | } 111 | 112 | - (NSRect)expansionFrameWithFrame:(NSRect)cellFrame inView:(NSView *)view 113 | { 114 | return NSZeroRect; 115 | } 116 | 117 | - (void)drawWithExpansionFrame:(NSRect)cellFrame inView:(NSView *)view 118 | { 119 | return; 120 | } 121 | @end -------------------------------------------------------------------------------- /Classes/CPFileReference.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPFileReference.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/15/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPFileReference.h" 10 | #import "CPCodePilotConfig.h" 11 | #import "CPXcodeInterfaces.h" 12 | #import "objc/objc-class.h" 13 | 14 | @implementation CPFileReference 15 | - (CPFileReference *)initWithDVTFilePath:(DVTFilePath *)dvtFilePath 16 | { 17 | return [self initWithFileURL:[dvtFilePath fileURL]]; 18 | } 19 | 20 | - (CPFileReference *)initWithFileURL:(NSURL *)fileURL 21 | { 22 | self = [super init]; 23 | 24 | if (self) { 25 | self.fileURL = fileURL; 26 | self.fileName = [fileURL lastPathComponent]; 27 | self.absolutePath = [fileURL path]; 28 | self.isGroup = NO; 29 | self.subprojectFile = NO; 30 | self.groupName = nil; 31 | self.isOpenable = !self.isGroup; 32 | self.isSearchable = YES; 33 | self.isOpenableInEditor = self.isOpenable; 34 | 35 | if (!IsEmpty(self.absolutePath) && 36 | [[NSFileManager defaultManager] fileExistsAtPath:self.absolutePath]) { 37 | DVTFilePath *dvtFilePath = [DVTFilePath filePathForPathString:self.absolutePath]; 38 | self.icon = [dvtFilePath navigableItem_image]; 39 | } 40 | } 41 | 42 | return self; 43 | } 44 | 45 | - (CPFileReference *)initWithPBXFileReference:(PBXFileReference *)pbxFileReference 46 | { 47 | self = [super init]; 48 | 49 | if (self) { 50 | if (![CPFileReference pbxFileReferenceIsImportable:pbxFileReference]) { 51 | return nil; 52 | } 53 | 54 | self.fileName = [pbxFileReference name]; 55 | self.absolutePath = [pbxFileReference resolvedAbsolutePath]; 56 | self.originalClassName = NSStringFromClass([pbxFileReference class]); 57 | self.isGroup = [pbxFileReference isGroup]; 58 | 59 | self.subprojectFile = NO; 60 | 61 | if (!IsEmpty(self.absolutePath)) { 62 | self.fileURL = [NSURL fileURLWithPath:self.absolutePath]; 63 | } 64 | 65 | self.groupName = nil; 66 | 67 | @try { 68 | self.groupName = [[pbxFileReference group] name]; 69 | 70 | PBXContainer *projectContainer = [pbxFileReference container]; 71 | 72 | if (nil != projectContainer) { 73 | self.projectName = [projectContainer name]; 74 | } 75 | } 76 | @catch (NSException * e) { 77 | LOG(@"EXCEPTION: %@", e); 78 | } 79 | 80 | self.icon = nil; 81 | 82 | self.isOpenable = !self.isGroup; 83 | self.isSearchable = YES; 84 | self.isOpenableInEditor = self.isOpenable; 85 | 86 | if ([pbxFileReference isGroup]) { 87 | self.icon = [[[IDEGroup alloc] init] navigableItem_image]; 88 | } else { 89 | if (!IsEmpty(self.absolutePath) && [[NSFileManager defaultManager] fileExistsAtPath:self.absolutePath]) { 90 | DVTFilePath *dvtFilePath = [DVTFilePath filePathForPathString:self.absolutePath]; 91 | self.icon = [dvtFilePath navigableItem_image]; 92 | } 93 | } 94 | } 95 | 96 | return self; 97 | } 98 | 99 | - (NSString *)description 100 | { 101 | return [NSString stringWithFormat:@"<%@: fileName: %@ groupName: %@ absolutePath: %@", 102 | [super description], self.fileName, self.groupName, self.absolutePath]; 103 | } 104 | 105 | - (NSString *)name 106 | { 107 | return self.fileName; 108 | } 109 | 110 | - (NSString *)sourceFile 111 | { 112 | return [[self.fileURL path] lastPathComponent]; 113 | } 114 | 115 | - (id)copyWithZone:(NSZone *)zone 116 | { 117 | CPFileReference *newSelf = [[[self class] allocWithZone:zone] init]; 118 | 119 | newSelf.fileName = self.fileName; 120 | newSelf.groupName = self.groupName; 121 | newSelf.icon = self.icon; 122 | newSelf.absolutePath = self.absolutePath; 123 | newSelf.projectName = self.projectName; 124 | newSelf.subprojectFile = self.subprojectFile; 125 | newSelf.originalClassName = self.originalClassName; 126 | newSelf.isGroup = self.isGroup; 127 | newSelf.isOpenable = self.isOpenable; 128 | newSelf.isSearchable = self.isSearchable; 129 | 130 | return newSelf; 131 | } 132 | 133 | - (BOOL)isEqualToPbxReference:(PBXFileReference *)pbxReference 134 | { 135 | CPFileReference *tmpRef = [[CPFileReference alloc] initWithPBXFileReference:pbxReference]; 136 | 137 | // group name, project name and subproject status aren't compared any more, as 138 | // xcode tends to confuse those for subprojects 139 | return ([tmpRef.absolutePath isEqualToString:self.absolutePath] && 140 | [tmpRef.fileName isEqualToString:self.fileName] && 141 | (tmpRef.isGroup == self.isGroup)); 142 | } 143 | 144 | + (BOOL)pbxFileReferenceIsImportable:(PBXFileReference *)pbxFileReference 145 | { 146 | if (nil == pbxFileReference) { 147 | return NO; 148 | } 149 | 150 | PBXFileType *fileType = [pbxFileReference fileType]; 151 | if (fileType == nil) { 152 | // xibs and folders don't have a filetype 153 | return YES; 154 | } 155 | 156 | if ([fileType isBundle] || 157 | [fileType isApplication] || 158 | [fileType isLibrary] || 159 | [fileType isFramework] || 160 | [fileType isProjectWrapper] || 161 | [fileType isTargetWrapper]/* || 162 | [fileType isExecutable] */) { // ruby files return true for isExecutable. 163 | return NO; 164 | } 165 | 166 | return YES; 167 | } 168 | 169 | - (double)scoreOffset 170 | { 171 | return [self isImplementation] ? 16.01 : 16; 172 | } 173 | @end -------------------------------------------------------------------------------- /Classes/AMIndeterminateProgressIndicatorCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // AMIndeterminateProgressIndicatorCell.m 3 | // IPICellTest 4 | // 5 | // Created by Andreas on 23.01.07. 6 | // Copyright 2007 Andreas Mayer. All rights reserved. 7 | // 8 | 9 | // 2007-03-10 Andreas Mayer 10 | // - removed -keyEquivalent and -keyEquivalentModifierMask methods 11 | // (I thought those were required by NSTableView/Column. They are not. 12 | // Instead I was using NSButtons as a container for the cells in the demo project. 13 | // Replacing those with plain NSControls did fix the problem.) 14 | // 2007-03-24 Andreas Mayer 15 | // - will now spin in the same direction in flipped and not flipped views 16 | // 2008-09-03 Andreas Mayer 17 | // - restore default settings for NSBezierPath after drawing 18 | // - instead of the saturation, we now modify the lines' opacity; does look better on colored 19 | // backgrounds 20 | 21 | #import "AMIndeterminateProgressIndicatorCell.h" 22 | 23 | #define ConvertAngle(a) (fmod((90.0-(a)), 360.0)) 24 | 25 | #define DEG2RAD 0.017453292519943295 26 | 27 | @implementation AMIndeterminateProgressIndicatorCell 28 | 29 | - (id)init 30 | { 31 | if ((self = [super initImageCell:nil])) { 32 | [self setAnimationDelay:5.0/60.0]; 33 | [self setDisplayedWhenStopped:YES]; 34 | [self setDoubleValue:0.0]; 35 | [self setColor:[NSColor greenColor]]; 36 | } 37 | return self; 38 | } 39 | 40 | 41 | - (NSColor *)color 42 | { 43 | return color; 44 | } 45 | 46 | - (void)setColor:(NSColor *)value 47 | { 48 | CGFloat alphaComponent; 49 | if (color != value) { 50 | color = value; 51 | [[color colorUsingColorSpaceName:@"NSCalibratedRGBColorSpace"] getRed:&redComponent green:&greenComponent blue:&blueComponent alpha:&alphaComponent]; 52 | // NSAssert((alphaComponent > 0.999), @"color must be opaque"); // gives a warning in xcode4 53 | } 54 | } 55 | 56 | - (double)doubleValue 57 | { 58 | return doubleValue; 59 | } 60 | 61 | - (void)setDoubleValue:(double)value 62 | { 63 | if (doubleValue != value) { 64 | doubleValue = value; 65 | if (doubleValue > 1.0) { 66 | doubleValue = 1.0; 67 | } else if (doubleValue < 0.0) { 68 | doubleValue = 0.0; 69 | } 70 | } 71 | } 72 | 73 | - (NSTimeInterval)animationDelay 74 | { 75 | return animationDelay; 76 | } 77 | 78 | - (void)setAnimationDelay:(NSTimeInterval)value 79 | { 80 | if (animationDelay != value) { 81 | animationDelay = value; 82 | } 83 | } 84 | 85 | - (BOOL)isDisplayedWhenStopped 86 | { 87 | return displayedWhenStopped; 88 | } 89 | 90 | - (void)setDisplayedWhenStopped:(BOOL)value 91 | { 92 | if (displayedWhenStopped != value) { 93 | displayedWhenStopped = value; 94 | } 95 | } 96 | 97 | - (BOOL)isSpinning 98 | { 99 | return spinning; 100 | } 101 | 102 | - (void)setSpinning:(BOOL)value 103 | { 104 | if (spinning != value) { 105 | spinning = value; 106 | } 107 | } 108 | 109 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 110 | { 111 | // cell has no border 112 | [self drawInteriorWithFrame:cellFrame inView:controlView]; 113 | } 114 | 115 | - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 116 | { 117 | //NSLog(@"cellFrame: %f %f %f %f", cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); 118 | if ([self isSpinning] || [self isDisplayedWhenStopped]) { 119 | float flipFactor = ([controlView isFlipped] ? 1.0 : -1.0); 120 | int step = round([self doubleValue]/(5.0/60.0)); 121 | float cellSize = MIN(cellFrame.size.width, cellFrame.size.height); 122 | NSPoint center = cellFrame.origin; 123 | center.x += cellSize/2.0; 124 | center.y += cellFrame.size.height/2.0; 125 | float outerRadius; 126 | float innerRadius; 127 | float strokeWidth = cellSize*0.08; 128 | if (cellSize >= 32.0) { 129 | outerRadius = cellSize*0.38; 130 | innerRadius = cellSize*0.23; 131 | } else { 132 | outerRadius = cellSize*0.48; 133 | innerRadius = cellSize*0.27; 134 | } 135 | float a; // angle 136 | NSPoint inner; 137 | NSPoint outer; 138 | // remember defaults 139 | NSLineCapStyle previousLineCapStyle = [NSBezierPath defaultLineCapStyle]; 140 | float previousLineWidth = [NSBezierPath defaultLineWidth]; 141 | // new defaults for our loop 142 | [NSBezierPath setDefaultLineCapStyle:NSRoundLineCapStyle]; 143 | [NSBezierPath setDefaultLineWidth:strokeWidth]; 144 | if ([self isSpinning]) { 145 | a = (270+(step* 30))*DEG2RAD; 146 | } else { 147 | a = 270*DEG2RAD; 148 | } 149 | a = flipFactor*a; 150 | int i; 151 | for (i = 0; i < 12; i++) { 152 | // [[NSColor colorWithCalibratedWhite:MIN(sqrt(i)*0.25, 0.8) alpha:1.0] set]; 153 | // [[NSColor colorWithCalibratedWhite:0.0 alpha:1.0-sqrt(i)*0.25] set]; 154 | [[NSColor colorWithCalibratedRed:redComponent green:greenComponent blue:blueComponent alpha:1.0-sqrt(i)*0.25] set]; 155 | // [[NSColor colorWithCalibratedRed:1.0 green:0 blue:0 alpha:1.0-sqrt(i)*0.25] set]; 156 | outer = NSMakePoint(center.x+cos(a)*outerRadius, center.y+sin(a)*outerRadius); 157 | inner = NSMakePoint(center.x+cos(a)*innerRadius, center.y+sin(a)*innerRadius); 158 | [NSBezierPath strokeLineFromPoint:inner toPoint:outer]; 159 | a -= flipFactor*30*DEG2RAD; 160 | } 161 | // restore previous defaults 162 | [NSBezierPath setDefaultLineCapStyle:previousLineCapStyle]; 163 | [NSBezierPath setDefaultLineWidth:previousLineWidth]; 164 | } 165 | } 166 | 167 | - (void)setObjectValue:(id)value 168 | { 169 | if ([value respondsToSelector:@selector(boolValue)]) { 170 | [self setSpinning:[value boolValue]]; 171 | } else { 172 | [self setSpinning:NO]; 173 | } 174 | } 175 | 176 | 177 | @end 178 | -------------------------------------------------------------------------------- /Classes/CPSymbolCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPSymbolCell.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/15/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPSymbolCell.h" 10 | #import "CPCodePilotConfig.h" 11 | #import "CPSymbol.h" 12 | #import "NSColor+ColorArithmetic.h" 13 | 14 | @implementation CPSymbolCell 15 | @dynamic cpSymbol; 16 | 17 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 18 | { 19 | [super drawWithFrame:cellFrame inView:controlView]; 20 | 21 | if (nil == self.cpSymbol || IsEmpty([self.cpSymbol name]) || 22 | (IsEmpty([self.cpSymbol sourceFile]) && [self.cpSymbol isKindOfClass:[CPSymbol class]])) { 23 | return; 24 | } 25 | 26 | [self drawSymbolNameWithFrame:cellFrame]; 27 | 28 | if (self.extendedDisplay) { 29 | [self drawSourceFileNameWithFrame:cellFrame]; 30 | } 31 | 32 | [self drawIconImage:[self.cpSymbol icon] withFrame:cellFrame]; 33 | } 34 | 35 | - (void)drawSymbolNameWithFrame:(NSRect)cellFrame 36 | { 37 | NSMutableDictionary *symbolNameStringAttributes = [[self defaultStringAttributes] mutableCopy]; 38 | NSColor *symbolNameForegroundColor = [self isHighlighted] ? [self symbolNameForegroundColorWithHighlight] : [self symbolNameForegroundColorWithoutHighlight]; 39 | 40 | [symbolNameStringAttributes setObject:[NSFont fontWithName:SYMBOL_SELECTION_CELL_FONT_NAME 41 | size:SYMBOL_SELECTION_CELL_FONT_SIZE] 42 | forKey:NSFontAttributeName]; 43 | 44 | [symbolNameStringAttributes setObject:symbolNameForegroundColor 45 | forKey:NSForegroundColorAttributeName]; 46 | 47 | NSMutableAttributedString *symbolNameAttributedString = [[self queryHitAttributedStringWithString:[self.cpSymbol name]] mutableCopy]; 48 | [symbolNameAttributedString addAttributes:symbolNameStringAttributes range:NSMakeRange(0, [symbolNameAttributedString length])]; 49 | 50 | CGFloat iconWidth = self.extendedDisplay ? RESULT_CELL_SYMBOL_EXTENDED_ICON_WIDTH : RESULT_CELL_SYMBOL_ICON_WIDTH; 51 | CGFloat symbolNameOffsetY = self.extendedDisplay ? 4 : 3; 52 | 53 | [symbolNameAttributedString drawInRect:NSMakeRect(cellFrame.origin.x + iconWidth, cellFrame.origin.y + symbolNameOffsetY, cellFrame.size.width - iconWidth, cellFrame.size.height)]; 54 | } 55 | 56 | - (void)drawSourceFileNameWithFrame:(NSRect)cellFrame 57 | { 58 | NSString *sourceFilename = [self.cpSymbol sourceFile]; 59 | 60 | if (sourceFilename) { 61 | sourceFilename = [[sourceFilename componentsSeparatedByString:@"/"] lastObject]; 62 | 63 | NSMutableDictionary *symbolFileNameStringAttributes = [[self defaultStringAttributes] mutableCopy]; 64 | 65 | [symbolFileNameStringAttributes setObject:[NSFont fontWithName:SYMBOL_SELECTION_CELL_EXTENDED_INFO_FONT_NAME 66 | size:SYMBOL_SELECTION_CELL_EXTENDED_INFO_FONT_SIZE] 67 | forKey:NSFontAttributeName]; 68 | 69 | if ([self isHighlighted]) { 70 | [symbolFileNameStringAttributes setObject:SYMBOL_SELECTION_CELL_HIGHLIGHTED_EXTENDED_INFO_COLOR 71 | forKey:NSForegroundColorAttributeName]; 72 | } else { 73 | [symbolFileNameStringAttributes setObject:SYMBOL_SELECTION_CELL_EXTENDED_INFO_COLOR 74 | forKey:NSForegroundColorAttributeName]; 75 | } 76 | 77 | NSAttributedString *symbolFileNameString = [[NSAttributedString alloc] initWithString:sourceFilename 78 | attributes:symbolFileNameStringAttributes]; 79 | 80 | CGFloat iconMargin; 81 | if (self.extendedDisplay) { 82 | iconMargin = RESULT_CELL_SYMBOL_EXTENDED_ICON_WIDTH; 83 | } else { 84 | iconMargin = RESULT_CELL_SYMBOL_ICON_WIDTH; 85 | } 86 | 87 | const CGFloat CellFrameOffsetX = iconMargin; 88 | const CGFloat CellFrameOffsetY = SYMBOL_SELECTION_CELL_FONT_SIZE + 9; 89 | 90 | [symbolFileNameString drawInRect:NSMakeRect(cellFrame.origin.x + CellFrameOffsetX, 91 | cellFrame.origin.y + CellFrameOffsetY, 92 | cellFrame.size.width - CellFrameOffsetX, 93 | cellFrame.size.height - CellFrameOffsetY)]; 94 | } 95 | } 96 | 97 | - (CPSymbol *)cpSymbol 98 | { 99 | return (CPSymbol *)self.objectValue; 100 | } 101 | 102 | - (NSUInteger)requiredHeight 103 | { 104 | if (self.extendedDisplay) { 105 | return SYMBOL_SELECTION_CELL_EXTENDED_HEIGHT; 106 | } else { 107 | return SYMBOL_SELECTION_CELL_HEIGHT; 108 | } 109 | } 110 | 111 | - (NSColor *)symbolNameForegroundColorWithoutHighlight 112 | { 113 | NSColor *standardColor = [self symbolNameForegroundColor]; 114 | 115 | return [standardColor colorWithAlphaComponent:[standardColor alphaComponent] * 0.7]; 116 | } 117 | 118 | - (NSColor *)symbolNameForegroundColorWithHighlight 119 | { 120 | return [self symbolNameForegroundColor]; 121 | } 122 | 123 | - (NSColor *)symbolNameForegroundColor 124 | { 125 | const static CGPoint ForegroundColorPositionOnStandardBitmap = {2, 2}; 126 | const static CGPoint ForegroundColorPositionOnRetinaBitmap = {4, 4}; 127 | 128 | if ([self.cpSymbol icon]) { 129 | NSData *tiffRepData = [[self.cpSymbol icon] TIFFRepresentation]; 130 | NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithData:tiffRepData]; 131 | if (bitmapRep) { 132 | BOOL iconUsesRetinaResolution = [bitmapRep pixelsWide] > [self.cpSymbol icon].size.width; 133 | CGPoint position = iconUsesRetinaResolution ? ForegroundColorPositionOnRetinaBitmap : ForegroundColorPositionOnStandardBitmap; 134 | NSColor *colorFromBitmap = [bitmapRep colorAtX:position.x y:position.y]; 135 | NSColor *foregroundColor; 136 | 137 | // now let's avoid low alpha and lighten up the dark colors 138 | if ([colorFromBitmap isDark]) { 139 | foregroundColor = [colorFromBitmap colorByMutliplyingComponentsBy:2]; 140 | 141 | } else { 142 | foregroundColor = colorFromBitmap; 143 | } 144 | 145 | return [foregroundColor colorWithAlphaComponent:1]; 146 | } 147 | } 148 | 149 | return SYMBOL_OTHER_NAME_COLOR; 150 | } 151 | 152 | - (NSColor *)symbolCategoryNameForegroundColor 153 | { 154 | // now let's avoid low alpha and lighten up the dark colors 155 | return [[[self symbolNameForegroundColor] colorByMutliplyingComponentsBy:0.8] colorWithAlphaComponent:1]; 156 | } 157 | 158 | - (NSRect)expansionFrameWithFrame:(NSRect)cellFrame inView:(NSView *)view 159 | { 160 | return NSZeroRect; 161 | } 162 | 163 | - (void)drawWithExpansionFrame:(NSRect)cellFrame inView:(NSView *)view 164 | { 165 | return; 166 | } 167 | @end -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # .gitignore file for Xcode4 and Xcode5 Source projects 3 | # 4 | # Apple bugs, waiting for Apple to fix/respond: 5 | # 6 | # 15564624 - what does the xccheckout file in Xcode5 do? Where's the documentation? 7 | # 8 | # Version 2.3 9 | # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects 10 | # 11 | # 2014 updates: 12 | # - appended non-standard items DISABLED by default (uncomment if you use those tools) 13 | # - removed the edit that an SO.com moderator made without bothering to ask me 14 | # - researched CocoaPods .lock more carefully, thanks to Gokhan Celiker 15 | # 2013 updates: 16 | # - fixed the broken "save personal Schemes" 17 | # - added line-by-line explanations for EVERYTHING (some were missing) 18 | # 19 | # NB: if you are storing "built" products, this WILL NOT WORK, 20 | # and you should use a different .gitignore (or none at all) 21 | # This file is for SOURCE projects, where there are many extra 22 | # files that we want to exclude 23 | # 24 | ######################### 25 | 26 | ##### 27 | # OS X temporary files that should never be committed 28 | # 29 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 30 | 31 | .DS_Store 32 | 33 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 34 | 35 | .Trashes 36 | 37 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 38 | 39 | *.swp 40 | 41 | # 42 | # *.lock - this is used and abused by many editors for many different things. 43 | # For the main ones I use (e.g. Eclipse), it should be excluded 44 | # from source-control, but YMMV. 45 | # (lock files are usually local-only file-synchronization on the local FS that should NOT go in git) 46 | # c.f. the "OPTIONAL" section at bottom though, for tool-specific variations! 47 | 48 | *.lock 49 | 50 | 51 | # 52 | # profile - REMOVED temporarily (on double-checking, I can't find it in OS X docs?) 53 | #profile 54 | 55 | 56 | #### 57 | # Xcode temporary files that should never be committed 58 | # 59 | # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... 60 | 61 | *~.nib 62 | 63 | 64 | #### 65 | # Xcode build files - 66 | # 67 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" 68 | 69 | DerivedData/ 70 | 71 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" 72 | 73 | build/ 74 | 75 | 76 | ##### 77 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) 78 | # 79 | # This is complicated: 80 | # 81 | # SOMETIMES you need to put this file in version control. 82 | # Apple designed it poorly - if you use "custom executables", they are 83 | # saved in this file. 84 | # 99% of projects do NOT use those, so they do NOT want to version control this file. 85 | # ..but if you're in the 1%, comment out the line "*.pbxuser" 86 | 87 | # .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html 88 | 89 | *.pbxuser 90 | 91 | # .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 92 | 93 | *.mode1v3 94 | 95 | # .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 96 | 97 | *.mode2v3 98 | 99 | # .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file 100 | 101 | *.perspectivev3 102 | 103 | # NB: also, whitelist the default ones, some projects need to use these 104 | !default.pbxuser 105 | !default.mode1v3 106 | !default.mode2v3 107 | !default.perspectivev3 108 | 109 | 110 | #### 111 | # Xcode 4 - semi-personal settings 112 | # 113 | # 114 | # OPTION 1: --------------------------------- 115 | # throw away ALL personal settings (including custom schemes! 116 | # - unless they are "shared") 117 | # 118 | # NB: this is exclusive with OPTION 2 below 119 | xcuserdata 120 | 121 | # OPTION 2: --------------------------------- 122 | # get rid of ALL personal settings, but KEEP SOME OF THEM 123 | # - NB: you must manually uncomment the bits you want to keep 124 | # 125 | # NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X, 126 | # or manually install git over the top of the OS X version 127 | # NB: this is exclusive with OPTION 1 above 128 | # 129 | #xcuserdata/**/* 130 | 131 | # (requires option 2 above): Personal Schemes 132 | # 133 | #!xcuserdata/**/xcschemes/* 134 | 135 | #### 136 | # XCode 4 workspaces - more detailed 137 | # 138 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :) 139 | # 140 | # Workspace layout is quite spammy. For reference: 141 | # 142 | # /(root)/ 143 | # /(project-name).xcodeproj/ 144 | # project.pbxproj 145 | # /project.xcworkspace/ 146 | # contents.xcworkspacedata 147 | # /xcuserdata/ 148 | # /(your name)/xcuserdatad/ 149 | # UserInterfaceState.xcuserstate 150 | # /xcsshareddata/ 151 | # /xcschemes/ 152 | # (shared scheme name).xcscheme 153 | # /xcuserdata/ 154 | # /(your name)/xcuserdatad/ 155 | # (private scheme).xcscheme 156 | # xcschememanagement.plist 157 | # 158 | # 159 | 160 | #### 161 | # Xcode 4 - Deprecated classes 162 | # 163 | # Allegedly, if you manually "deprecate" your classes, they get moved here. 164 | # 165 | # We're using source-control, so this is a "feature" that we do not want! 166 | 167 | *.moved-aside 168 | 169 | #### 170 | # OPTIONAL: Some well-known tools that people use side-by-side with Xcode / iOS development 171 | # 172 | # NB: I'd rather not include these here, but gitignore's design is weak and doesn't allow 173 | # modular gitignore: you have to put EVERYTHING in one file. 174 | # 175 | # COCOAPODS: 176 | # 177 | # c.f. http://guides.cocoapods.org/using/using-cocoapods.html#what-is-a-podfilelock 178 | # c.f. http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 179 | # 180 | #!Podfile.lock 181 | # 182 | # RUBY: 183 | # 184 | # c.f. http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ 185 | # 186 | #!Gemfile.lock 187 | # 188 | # IDEA: 189 | # 190 | #.idea 191 | # 192 | # TEXTMATE: 193 | # 194 | # -- UNVERIFIED: c.f. http://stackoverflow.com/a/50283/153422 195 | # 196 | #tm_build_errors 197 | 198 | #### 199 | # UNKNOWN: recommended by others, but I can't discover what these files are 200 | # 201 | # Community suggestions (unverified, no evidence available - DISABLED by default) 202 | # 203 | # 1. Xcode 5 - VCS file 204 | # 205 | # "The data in this file not represent state of your project. 206 | # If you'll leave this file in git - you will have merge conflicts during 207 | # pull your cahnges to other's repo" 208 | # 209 | #*.xccheckout 210 | -------------------------------------------------------------------------------- /Classes/CPSymbol.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPSymbol.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/15/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPFileReference.h" 10 | #import "CPSymbol.h" 11 | #import 12 | 13 | @interface CPSymbol () 14 | @property (nonatomic, assign, readwrite) BOOL hasOccurrences; 15 | @end 16 | 17 | @implementation CPSymbol 18 | - (CPSymbol *)init 19 | { 20 | self = [super init]; 21 | 22 | if (self) { 23 | self.childrenCache = [NSArray array]; 24 | self.cachedRelatedSymbolOccurrence = nil; 25 | self.hasOccurrences = YES; 26 | } 27 | 28 | return self; 29 | } 30 | 31 | - (CPSymbol *)initWithIDEIndexSymbol:(IDEIndexSymbol *)ideIndexSymbol forCPFileReference:(CPFileReference *)fileReference 32 | { 33 | return [self initWithIDEIndexSymbol:ideIndexSymbol forRelatedFileAtPath:fileReference.absolutePath]; 34 | } 35 | 36 | - (CPSymbol *)initWithIDEIndexSymbol:(IDEIndexSymbol *)ideIndexSymbol forRelatedFileAtPath:(NSString *)relatedFilePath 37 | { 38 | self = [self init]; 39 | 40 | if (self) { 41 | self.wrappedObject = ideIndexSymbol; 42 | self.relatedFilePath = relatedFilePath; 43 | } 44 | 45 | return self; 46 | } 47 | 48 | - (void)logOccurrences 49 | { 50 | LOG(@"============= %@", self); 51 | 52 | LOG(@"=== modelOccurrence: %@", [self.wrappedObject modelOccurrence]); 53 | 54 | LOG(@"=== DECLARATIONS", self); 55 | for (IDEIndexSymbolOccurrence *occurrence in [self.wrappedObject declarations]) { 56 | LOG(@"%@ - file: %@ location %@ lineNumber %d", occurrence, [occurrence file], [occurrence location], [occurrence lineNumber]); 57 | } 58 | 59 | LOG(@"=== DEFINITIONS", self); 60 | for (IDEIndexSymbolOccurrence *occurrence in [self.wrappedObject definitions]) { 61 | LOG(@"%@ - file: %@ location %@ lineNumber %d", occurrence, [occurrence file], [occurrence location], [occurrence lineNumber]); 62 | } 63 | 64 | LOG(@"=== OCCURRENCES", self); 65 | for (IDEIndexSymbolOccurrence *occurrence in [self.wrappedObject occurrences]) { 66 | LOG(@"%@ - file: %@ location %@ lineNumber %d", occurrence, [occurrence file], [occurrence location], [occurrence lineNumber]); 67 | } 68 | } 69 | 70 | - (DVTTextDocumentLocation *)relatedDocumentLocation 71 | { 72 | IDEIndexSymbolOccurrence *occurrence = [self relatedSymbolOccurrence]; 73 | 74 | NSNumber *timestamp = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]]; 75 | 76 | return [[DVTTextDocumentLocation alloc] initWithDocumentURL:[[occurrence file] fileURL] 77 | timestamp:timestamp 78 | lineRange:NSMakeRange([occurrence lineNumber] - 1, 1)]; 79 | } 80 | 81 | - (void)cacheRelatedSymbolOccurrence 82 | { 83 | if (nil == self.cachedRelatedSymbolOccurrence && _hasOccurrences) { 84 | NSArray *orderedOccurrences = [NSArray array]; 85 | 86 | NSArray *occurrences = [[self.wrappedObject occurrences] allObjects]; 87 | NSArray *definitions = [[self.wrappedObject definitions] allObjects]; 88 | 89 | if ([occurrences count] > 0) { 90 | orderedOccurrences = [orderedOccurrences arrayByAddingObjectsFromArray:definitions]; 91 | orderedOccurrences = [orderedOccurrences arrayByAddingObjectsFromArray:occurrences]; 92 | 93 | for (IDEIndexSymbolOccurrence *occurrence in orderedOccurrences) { 94 | if (IsEmpty(self.relatedFilePath) || [[[occurrence file] pathString] isEqualToString:self.relatedFilePath]) { 95 | self.cachedRelatedSymbolOccurrence = occurrence; 96 | break; 97 | } 98 | } 99 | 100 | self.cachedRelatedSymbolOccurrence = self.cachedRelatedSymbolOccurrence ?: [orderedOccurrences objectAtIndex:0]; 101 | 102 | } else { 103 | self.hasOccurrences = NO; 104 | LOG(@"WARNING: no occurrences found for symbol: %@", self); 105 | } 106 | } 107 | } 108 | 109 | - (IDEIndexSymbolOccurrence *)relatedSymbolOccurrence 110 | { 111 | [self cacheRelatedSymbolOccurrence]; 112 | 113 | return self.cachedRelatedSymbolOccurrence; 114 | } 115 | 116 | - (NSImage *)icon 117 | { 118 | return [self.wrappedObject icon]; 119 | } 120 | 121 | - (NSString *)originalClassName 122 | { 123 | return [self.wrappedObject className]; 124 | } 125 | 126 | - (NSString *)sourceFile 127 | { 128 | if (nil != [self relatedSymbolOccurrence]) { 129 | NSURL *sourceFileURL = [[[self relatedSymbolOccurrence] file] fileURL]; 130 | return [sourceFileURL lastPathComponent]; 131 | } 132 | 133 | return @"(sourceFile)"; 134 | } 135 | 136 | - (NSString *)name 137 | { 138 | return [self.wrappedObject name]; 139 | } 140 | 141 | - (BOOL)isEqualToIDEIndexSymbol:(id)ideIndexSymbol 142 | { 143 | return (self.wrappedObject == ideIndexSymbol); 144 | } 145 | 146 | - (NSString *)description 147 | { 148 | return [NSString stringWithFormat:@"<%@: originalClassName: %@ name: %@ sourceFile: %@ >", [super description], self.originalClassName, self.name, self.sourceFile]; 149 | } 150 | 151 | - (id)copyWithZone:(NSZone *)zone 152 | { 153 | CPSymbol *newSelf = [[[self class] allocWithZone:zone] init]; 154 | newSelf.wrappedObject = self.wrappedObject; 155 | return newSelf; 156 | } 157 | 158 | // we can list the contents 159 | - (BOOL)isSearchable 160 | { 161 | return [self.wrappedObject isKindOfClass:[IDEIndexContainerSymbol class]]; 162 | } 163 | 164 | // we can open it with enter 165 | - (BOOL)isOpenable 166 | { 167 | return YES; 168 | } 169 | 170 | - (NSString *)symbolTypeName 171 | { 172 | NSMutableString *_name = [self.originalClassName mutableCopy]; 173 | 174 | MC_SED(_name, @"IDE", @""); 175 | MC_SED(_name, @"Symbol", @""); 176 | 177 | return [_name lowercaseString]; 178 | } 179 | 180 | - (BOOL)isCategory 181 | { 182 | return [self.wrappedObject isKindOfClass:[IDEIndexCategorySymbol class]]; 183 | } 184 | 185 | - (NSArray *)children 186 | { 187 | if ([self.wrappedObject isKindOfClass:[IDEIndexContainerSymbol class]] && 188 | 0 == [self.childrenCache count]) { 189 | self.childrenCache = [NSArray array]; 190 | 191 | for (IDEIndexSymbol *ideIndexSymbol in [(IDEIndexContainerSymbol *)self.wrappedObject children]) { 192 | CPSymbol *childSymbol = [[CPSymbol alloc] initWithIDEIndexSymbol:ideIndexSymbol 193 | forRelatedFileAtPath:self.relatedFilePath]; 194 | 195 | self.childrenCache = [self.childrenCache arrayByAddingObject:childSymbol]; 196 | } 197 | } 198 | 199 | return self.childrenCache; 200 | } 201 | 202 | - (BOOL)hasOccurrences 203 | { 204 | [self cacheRelatedSymbolOccurrence]; 205 | 206 | return _hasOccurrences; 207 | } 208 | 209 | - (double)scoreOffset 210 | { 211 | return [self isImplementation] ? 0.01 : 0; 212 | } 213 | @end -------------------------------------------------------------------------------- /Classes/CPPreferencesView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPPreferencesView.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/10/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPPreferencesView.h" 10 | #import "CPCodePilotConfig.h" 11 | 12 | static const CGFloat PreferredViewWidth = 750.0f; 13 | static const CGFloat PreferredViewHeight = 250.0f; 14 | static const CGFloat Margin = 24; 15 | static const CGFloat LeftSideWidth = 200; 16 | static const CGFloat RightSideWidth = 420; 17 | static const CGFloat TextHeight = 16; 18 | 19 | @implementation CPPreferencesView 20 | - (id)initWithPreferredFrame 21 | { 22 | return [self initWithFrame:NSMakeRect(0.0f, 0.0f, PreferredViewWidth, PreferredViewHeight)]; 23 | } 24 | 25 | - (id)initWithFrame:(NSRect)frame 26 | { 27 | self = [super initWithFrame:frame]; 28 | 29 | if (self) { 30 | [self setAutoresizingMask:NSViewNotSizable]; 31 | 32 | [self setupAutoCopyingSelectionOption]; 33 | [self setupCopyrightLabel]; 34 | [self setupCreditsAndThanksLabels]; 35 | [self setupSeparatorView]; 36 | } 37 | 38 | return self; 39 | } 40 | 41 | - (void)setupAutoCopyingSelectionOption 42 | { 43 | NSButton *autocopyingSelectionCheckbox = [[NSButton alloc] initWithFrame:NSMakeRect(Margin, Margin, LeftSideWidth, TextHeight)]; 44 | 45 | autocopyingSelectionCheckbox.title = @"Auto-search for selected text"; 46 | autocopyingSelectionCheckbox.font = [self boldFont]; 47 | [autocopyingSelectionCheckbox setButtonType:NSSwitchButton]; 48 | 49 | 50 | if (nil == [[NSUserDefaults standardUserDefaults] objectForKey:DEFAULTS_AUTOCOPY_SELECTION_KEY]) { 51 | [autocopyingSelectionCheckbox setState:DEFAULT_AUTOCOPY_SELECTION_VALUE]; 52 | } else { 53 | [autocopyingSelectionCheckbox setState:[[NSUserDefaults standardUserDefaults] boolForKey:DEFAULTS_AUTOCOPY_SELECTION_KEY]]; 54 | } 55 | 56 | [autocopyingSelectionCheckbox sizeToFit]; 57 | 58 | self.autocopyingSelectionCheckbox = autocopyingSelectionCheckbox; 59 | 60 | [self addSubview:autocopyingSelectionCheckbox]; 61 | 62 | NSButton *externalEditorCheckbox = [[NSButton alloc] initWithFrame:NSMakeRect(Margin, Margin*1.5 + autocopyingSelectionCheckbox.bounds.size.height, LeftSideWidth, TextHeight)]; 63 | 64 | externalEditorCheckbox.title = @"Use external editor"; 65 | externalEditorCheckbox.font = [self boldFont]; 66 | [externalEditorCheckbox setButtonType:NSSwitchButton]; 67 | 68 | if (nil == [[NSUserDefaults standardUserDefaults] objectForKey:DEFAULTS_EXTERNAL_EDITOR_KEY]) { 69 | [externalEditorCheckbox setState:DEFAULT_EXTERNAL_EDITOR_SELECTION_VALUE]; 70 | } else { 71 | [externalEditorCheckbox setState:[[NSUserDefaults standardUserDefaults] boolForKey:DEFAULTS_EXTERNAL_EDITOR_KEY]]; 72 | } 73 | 74 | [externalEditorCheckbox sizeToFit]; 75 | 76 | self.externalEditorCheckbox = externalEditorCheckbox; 77 | 78 | [self addSubview:externalEditorCheckbox]; 79 | } 80 | 81 | - (void)setupCopyrightLabel 82 | { 83 | CGFloat left = self.frame.size.width - Margin - RightSideWidth; 84 | NSTextField *copyrightLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(left, Margin, RightSideWidth, TextHeight)]; 85 | 86 | copyrightLabel.stringValue = [NSString stringWithFormat:@"%@ %@ © 2014 Macoscope Sp. z o.o. All rights reserved.\nhttp://macoscope.com", PRODUCT_NAME, PRODUCT_CURRENT_VERSION]; 87 | copyrightLabel.font = [self boldFont]; 88 | copyrightLabel.bordered = NO; 89 | copyrightLabel.editable = NO; 90 | copyrightLabel.backgroundColor = [NSColor clearColor]; 91 | 92 | [copyrightLabel sizeToFit]; 93 | 94 | [self addSubview:copyrightLabel]; 95 | } 96 | 97 | - (void)setupCreditsAndThanksLabels 98 | { 99 | CGFloat left = self.frame.size.width - Margin - RightSideWidth; 100 | 101 | NSTextField *firstCreditsLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(left, Margin + TextHeight + Margin, RightSideWidth, TextHeight)]; 102 | 103 | firstCreditsLabel.stringValue = @"Credits:"; 104 | firstCreditsLabel.font = [self boldFont]; 105 | firstCreditsLabel.bordered = NO; 106 | firstCreditsLabel.editable = NO; 107 | firstCreditsLabel.backgroundColor = [NSColor clearColor]; 108 | 109 | [firstCreditsLabel sizeToFit]; 110 | 111 | NSTextField *secondCreditsLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(left, CGRectGetMaxY(firstCreditsLabel.frame), RightSideWidth, 10 * TextHeight)]; 112 | 113 | secondCreditsLabel.stringValue = CREDITS_STRING; 114 | secondCreditsLabel.font = [self font]; 115 | secondCreditsLabel.bordered = NO; 116 | secondCreditsLabel.editable = NO; 117 | secondCreditsLabel.backgroundColor = [NSColor clearColor]; 118 | 119 | [secondCreditsLabel sizeToFit]; 120 | 121 | NSTextField *firstThanksLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(left, CGRectGetMaxY(secondCreditsLabel.frame) + Margin, RightSideWidth, TextHeight)]; 122 | 123 | firstThanksLabel.stringValue = @"Thanks:"; 124 | firstThanksLabel.font = [self boldFont]; 125 | firstThanksLabel.bordered = NO; 126 | firstThanksLabel.editable = NO; 127 | firstThanksLabel.backgroundColor = [NSColor clearColor]; 128 | 129 | [firstThanksLabel sizeToFit]; 130 | 131 | NSTextField *secondThanksLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(left, CGRectGetMaxY(firstThanksLabel.frame), RightSideWidth, TextHeight)]; 132 | 133 | secondThanksLabel.stringValue = THANKS_STRING; 134 | secondThanksLabel.font = [self font]; 135 | secondThanksLabel.bordered = NO; 136 | secondThanksLabel.editable = NO; 137 | secondThanksLabel.backgroundColor = [NSColor clearColor]; 138 | 139 | [secondThanksLabel sizeToFit]; 140 | 141 | [self addSubview:firstCreditsLabel]; 142 | [self addSubview:secondCreditsLabel]; 143 | [self addSubview:firstThanksLabel]; 144 | [self addSubview:secondThanksLabel]; 145 | } 146 | 147 | - (void)setupSeparatorView 148 | { 149 | CGFloat position = Margin + LeftSideWidth + (self.frame.size.width - 2 * Margin - RightSideWidth - LeftSideWidth) / 2; 150 | 151 | NSView *separatorView = [[NSView alloc] initWithFrame:CGRectMake(position, self.frame.size.height * 0.1, 1, self.frame.size.height * 0.8)]; 152 | [separatorView setWantsLayer:YES]; 153 | separatorView.layer.backgroundColor = [[NSColor colorWithCalibratedRed:0.537 green:0.537 blue:0.537 alpha:1] CGColor]; 154 | 155 | [self addSubview:separatorView]; 156 | } 157 | 158 | - (NSFont *)boldFont 159 | { 160 | return [NSFont fontWithName:@"Helvetica-Bold" size:[self fontSize]]; 161 | } 162 | 163 | - (NSFont *)font 164 | { 165 | return [NSFont fontWithName:@"Helvetica" size:[self fontSize]]; 166 | } 167 | 168 | - (CGFloat)fontSize 169 | { 170 | return [NSFont systemFontSize]; 171 | } 172 | 173 | - (BOOL)isFlipped 174 | { 175 | return YES; 176 | } 177 | 178 | + (CGFloat)preferredWidth 179 | { 180 | return PreferredViewWidth; 181 | } 182 | 183 | + (CGFloat)preferredHeight 184 | { 185 | return PreferredViewHeight; 186 | } 187 | 188 | @end -------------------------------------------------------------------------------- /Classes/CPSearchField.m: -------------------------------------------------------------------------------- 1 | // 2 | // SearchField.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 2/27/10. 6 | // Copyright 2010 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPSearchField.h" 10 | #import "CPCodePilotConfig.h" 11 | #import "CPSearchController.h" 12 | #import "CPSelectedObjectCell.h" 13 | #import "NSView+RoundedFrame.h" 14 | #import "CPStatusLabel.h" 15 | #import "CPSymbol.h" 16 | #import "CPSearchFieldTextView.h" 17 | 18 | static NSString * const SelectedObjectKeyPath = @"selectedObject"; 19 | 20 | @implementation CPSearchField 21 | - (CPSearchField *)initWithFrame:(NSRect)frameRect 22 | { 23 | self = [super initWithFrame:frameRect]; 24 | 25 | if (self) { 26 | [self setDrawsBackground:NO]; 27 | [self setContinuous:YES]; 28 | [self setImportsGraphics:YES]; 29 | [self setTextColor:SEARCHFIELD_FONT_COLOR]; 30 | [self setFocusRingType:NSFocusRingTypeNone]; 31 | 32 | self.delay = DEFAULT_SEARCHFIELD_DELAY_VALUE; 33 | 34 | if (nil != [[NSUserDefaults standardUserDefaults] objectForKey:DEFAULTS_SEARCH_INTERVAL_KEY]) { 35 | self.delay = [[NSUserDefaults standardUserDefaults] floatForKey:DEFAULTS_SEARCH_INTERVAL_KEY]; 36 | USER_LOG(@"Custom user searchfield delay set to %f", self.delay); 37 | } 38 | 39 | NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 40 | [paragraphStyle setAlignment:NSCenterTextAlignment]; 41 | 42 | NSFont *placeholderFont = [NSFont fontWithName:SEARCHFIELD_PLACEHOLDER_FONT size:SEARCHFIELD_PLACEHOLDER_FONT_SIZE]; 43 | 44 | if (nil == placeholderFont) { 45 | placeholderFont = [NSFont fontWithName:SEARCHFIELD_PLACEHOLDER_ALTERNATIVE_FONT size:SEARCHFIELD_PLACEHOLDER_FONT_SIZE]; 46 | } 47 | 48 | NSDictionary *placeholderAttributes = [[NSDictionary alloc] initWithObjectsAndKeys: 49 | SEARCHFIELD_PLACEHOLDER_FONT_COLOR, NSForegroundColorAttributeName, 50 | paragraphStyle, NSParagraphStyleAttributeName, 51 | placeholderFont, NSFontAttributeName, nil]; 52 | 53 | NSAttributedString *placeholderAttributedString = [[NSAttributedString alloc] initWithString:SEARCHFIELD_PLACEHOLDER_STRING 54 | attributes:placeholderAttributes]; 55 | 56 | self.placeholderTextField = [[CPStatusLabel alloc] initWithFrame:NSMakeRect(-27, 4, self.frame.size.width, self.frame.size.height)]; 57 | [self.placeholderTextField setAttributedStringValue:placeholderAttributedString]; 58 | 59 | [self addSubview:self.placeholderTextField]; 60 | 61 | [self setFont:[NSFont fontWithName:SEARCHFIELD_FONT size:SEARCHFIELD_FONT_SIZE]]; 62 | 63 | [self addObserver:self 64 | forKeyPath:SelectedObjectKeyPath 65 | options:0 66 | context:nil]; 67 | 68 | [self letDelegateKnowAboutChangedQueries]; 69 | } 70 | 71 | return self; 72 | } 73 | 74 | - (void)dealloc 75 | { 76 | [self removeObserver:self forKeyPath:SelectedObjectKeyPath]; 77 | } 78 | 79 | - (void)setupDelegateNotificationAboutChangedQueriesTimer 80 | { 81 | if (nil != self.delegateNotificationAboutChangedQueriesTimer) { 82 | [self.delegateNotificationAboutChangedQueriesTimer invalidate]; 83 | } 84 | 85 | self.delegateNotificationAboutChangedQueriesTimer = [NSTimer scheduledTimerWithTimeInterval:self.delay 86 | target:self 87 | selector:@selector(letDelegateKnowAboutChangedQueries) 88 | userInfo:NULL 89 | repeats:NO]; 90 | 91 | [[NSRunLoop currentRunLoop] addTimer:self.delegateNotificationAboutChangedQueriesTimer 92 | forMode:NSEventTrackingRunLoopMode]; 93 | } 94 | 95 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 96 | { 97 | if ([keyPath isEqualToString:SelectedObjectKeyPath]) { 98 | [self selectedObjectDidChange]; 99 | } 100 | } 101 | 102 | - (void)selectedObjectDidChange 103 | { 104 | if (self.selectedObject) { 105 | NSTextAttachment *at = [[NSTextAttachment alloc] initWithFileWrapper:nil]; 106 | CPSelectedObjectCell *attachCell = [[CPSelectedObjectCell alloc] init]; 107 | 108 | [attachCell setTitle:[self.selectedObject name]]; 109 | [attachCell setAttachment:at]; 110 | [at setAttachmentCell: attachCell]; 111 | 112 | NSMutableAttributedString *as = [[NSAttributedString attributedStringWithAttachment: at] mutableCopy]; 113 | 114 | [self setStringValue:@" "]; 115 | NSMutableAttributedString *currentSpace = [[self attributedStringValue] mutableCopy]; 116 | 117 | // by default, text after the attachment gets lowered baseline, to start where the icon starts 118 | [currentSpace addAttribute:NSBaselineOffsetAttributeName 119 | value:[NSNumber numberWithFloat:3.0] 120 | range:NSMakeRange(0, [currentSpace length])]; 121 | 122 | [as appendAttributedString:currentSpace]; 123 | [self setAttributedStringValue:as]; 124 | 125 | self.symbolQuery = nil; 126 | } 127 | } 128 | 129 | - (void)reset 130 | { 131 | [self setStringValue:@""]; 132 | 133 | self.fileQuery = nil; 134 | self.symbolQuery = nil; 135 | self.selectedObject = nil; 136 | } 137 | 138 | - (BOOL)cmdBackspaceKeyDown 139 | { 140 | if (nil != self.selectedObject) { 141 | if (!IsEmpty(self.symbolQuery)) { 142 | // redo current symbol with empty query string when user 143 | // presses cmd-backspace in in-file-symbol-query-mode 144 | [self selectedObjectDidChange]; 145 | } else { 146 | // cmd-backspace when only file attachment is visible 147 | // in query results with total reset of the query 148 | [self reset]; 149 | } 150 | 151 | [self textDidChange:nil]; 152 | return YES; 153 | } 154 | 155 | return NO; // not handled here 156 | } 157 | 158 | // called from SearchFieldTextView 159 | - (BOOL)spaceKeyDown 160 | { 161 | if ([self delegate] && [[self delegate] respondsToSelector:@selector(spacePressedForSearchField:)]) { 162 | return [(CPSearchController *)[self delegate] spacePressedForSearchField:self]; 163 | } 164 | 165 | return NO; // not handled here. 166 | } 167 | 168 | // programmatic setting of the search query 169 | - (void)pasteString:(NSString *)str 170 | { 171 | [(CPSearchFieldTextView *)[self currentEditor] pasteString:str]; 172 | } 173 | 174 | - (void)textDidChange:(NSNotification *)aNotification 175 | { 176 | [self setupDelegateNotificationAboutChangedQueriesTimer]; 177 | 178 | if (self.selectedObject) { 179 | // stripping funny ascii representations of text attachments 180 | NSString *strValue = [self stringValue]; 181 | NSMutableString *tmpString = [NSMutableString new]; 182 | 183 | for (NSInteger i = 0; i < [strValue length]; i++) { 184 | unichar ch = [strValue characterAtIndex:i]; 185 | if (ch == ' ' || [[NSCharacterSet alphanumericCharacterSet] characterIsMember:ch]) { 186 | [tmpString appendFormat:@"%c", ch]; 187 | } 188 | } 189 | 190 | // backspace pressed where the situation was: "[object] " 191 | if (0 == [tmpString length]) { 192 | self.symbolQuery = nil; 193 | self.stringValue = self.fileQuery; 194 | self.selectedObject = nil; 195 | } else { 196 | self.symbolQuery = [tmpString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 197 | } 198 | } else { 199 | self.fileQuery = [self stringValue]; 200 | self.symbolQuery = nil; 201 | } 202 | } 203 | 204 | - (void)letDelegateKnowAboutChangedQueries 205 | { 206 | if ([self delegate] && [[self delegate] respondsToSelector:@selector(noteQueriesChanged)] && 207 | (!((CPSearchFieldTextView *)[self currentEditor]).someKeyIsDown)) { 208 | [self.delegate performSelector:@selector(noteQueriesChanged)]; 209 | } 210 | } 211 | 212 | - (id)copyWithZone:(NSZone *)zone 213 | { 214 | CPSearchField *newSelf = [[self class] new]; 215 | 216 | [newSelf disableObservers]; 217 | newSelf.fileQuery = self.fileQuery; 218 | newSelf.symbolQuery = self.symbolQuery; 219 | newSelf.selectedObject = self.selectedObject; 220 | 221 | return newSelf; 222 | } 223 | 224 | - (void)disableObservers 225 | { 226 | [self removeObserver:self forKeyPath:SelectedObjectKeyPath]; 227 | } 228 | 229 | // nil capable! super-power! 230 | - (void)setStringValue:(NSString *)str 231 | { 232 | [super setStringValue:str ?: @""]; 233 | } 234 | 235 | - (void)drawRect:(NSRect)dirtyRect 236 | { 237 | [self.placeholderTextField setHidden:!IsEmpty([self stringValue])]; 238 | } 239 | @end -------------------------------------------------------------------------------- /Classes/CPPluginInstaller.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPPluginInstaller.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 3/23/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPPluginInstaller.h" 10 | #import "CPCodePilotPlugin.h" 11 | #import "CPPreferencesToolbarDelegate.h" 12 | 13 | static NSString * const IDEKeyBindingSetDidActivateNotification = @"IDEKeyBindingSetDidActivateNotification"; 14 | 15 | @implementation CPPluginInstaller 16 | - (void)installPlugin:(CPCodePilotPlugin *)plugin 17 | { 18 | self.installedPlugin = plugin; 19 | 20 | [self installKeyBinding]; 21 | [self installMenuItem]; 22 | 23 | LOG(@"%@ %@ Plugin successfully installed.", PRODUCT_NAME, PRODUCT_CURRENT_VERSION); 24 | } 25 | 26 | - (id)init 27 | { 28 | self = [super init]; 29 | 30 | if (self) { 31 | [self setupKeyBindingsIfNeeded]; 32 | [self installNotificationListeners]; 33 | } 34 | 35 | return self; 36 | } 37 | 38 | - (void)installNotificationListeners 39 | { 40 | // listen for preferences editing FIXME/TODO - find some less insane method. 41 | [[NSNotificationCenter defaultCenter] addObserver:self 42 | selector:@selector(keyBindingsHaveChanged:) 43 | name:IDEKeyBindingSetDidActivateNotification 44 | object:nil]; 45 | 46 | [[NSNotificationCenter defaultCenter] addObserver:self 47 | selector:@selector(windowDidBecomeKey:) 48 | name:NSWindowDidBecomeKeyNotification 49 | object:nil]; 50 | } 51 | 52 | - (void)removeNotificationListeners 53 | { 54 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 55 | } 56 | 57 | - (void)windowDidBecomeKey:(NSNotification *)notification 58 | { 59 | NSWindow *window = [notification object]; 60 | 61 | if (nil != [window toolbar] && nil != [[window toolbar] delegate] && [[[window toolbar] delegate] isKindOfClass:[IDEPreferencesController class]]) { 62 | [self installPreferencePaneInToolbar:[window toolbar]]; 63 | } 64 | } 65 | 66 | - (void)installPreferencePaneInToolbar:(NSToolbar *)toolbar 67 | { 68 | self.toolbarDelegate = [CPPreferencesToolbarDelegate preferencesToolbarDelegateByInterceptingDelegateOfToolbar:toolbar]; 69 | } 70 | 71 | - (void)setupKeyBindingsIfNeeded 72 | { 73 | // this saves default shortcut into preferences if it's the first run and nothing is defined 74 | if (IsEmpty([self keyBindingFromUserDefaults])) { 75 | [self saveKeyBindingToUserDefaults:CP_DEFAULT_SHORTCUT forKey:DEFAULTS_KEY_BINDING]; 76 | } 77 | } 78 | 79 | - (NSString *)keyBindingFromUserDefaults 80 | { 81 | return [[NSUserDefaults standardUserDefaults] valueForKey:DEFAULTS_KEY_BINDING]; 82 | } 83 | 84 | - (void)saveKeyBindingToUserDefaults:(NSString *)keyBinding forKey:(NSString *)defaultsKey 85 | { 86 | [[NSUserDefaults standardUserDefaults] setObject:keyBinding forKey:defaultsKey]; 87 | [[NSUserDefaults standardUserDefaults] synchronize]; 88 | } 89 | 90 | // Okay, this is lame. 91 | // Since I couldn't figure out a way to create a proper extension points with 92 | // proper plugin structure - we're just adding a new option called "Code Pilot" 93 | // to the menu key bindings. Then we listen for any change that might have happened 94 | // with IDEKeyBindingSetDidActivateNotification notification and re-read it from 95 | // user's keybindings, to save it to NSUserDefaults where we will look to find 96 | // a custom setup to use in Code Pilot's NSMenuItem. 97 | // 98 | // The right way to fix it is to find a way to use .ideplugin structure, or 99 | // plugin plist definition (.xcplugindata or whatever it will be called) and define 100 | // proper extension points there along with whole menu/keybinding infrastructure. 101 | - (void)installKeyBinding 102 | { 103 | [self installStandardKeyBinding]; 104 | } 105 | 106 | - (void)installStandardKeyBinding 107 | { 108 | IDEKeyBindingPreferenceSet *currentPreferenceSet = [[IDEKeyBindingPreferenceSet preferenceSetsManager] currentPreferenceSet]; 109 | IDEMenuKeyBindingSet *menuKeyBindingSet = [currentPreferenceSet menuKeyBindingSet]; 110 | 111 | IDEKeyboardShortcut *defaultShortcut = [IDEKeyboardShortcut keyboardShortcutFromStringRepresentation:[self keyBindingFromUserDefaults]]; 112 | 113 | IDEMenuKeyBinding *cpKeyBinding; 114 | 115 | // older versions of Xcode 4 support another way of creating menukeybinding: 116 | if ([IDEMenuKeyBinding respondsToSelector:@selector(keyBindingWithTitle:group:actions:keyboardShortcuts:)]) { 117 | cpKeyBinding = [IDEMenuKeyBinding keyBindingWithTitle:CP_MENU_ITEM_TITLE 118 | group:CP_KEY_BINDING_MENU_NAME 119 | actions:[NSArray arrayWithObject:@"whatever:"] 120 | keyboardShortcuts:[NSArray arrayWithObject:defaultShortcut]]; 121 | } else { 122 | cpKeyBinding = [IDEMenuKeyBinding keyBindingWithTitle:CP_MENU_ITEM_TITLE 123 | parentTitle:@"foo" 124 | group:CP_KEY_BINDING_MENU_NAME 125 | actions:[NSArray arrayWithObject:@"whatever:"] 126 | keyboardShortcuts:[NSArray arrayWithObject:defaultShortcut]]; 127 | } 128 | 129 | [cpKeyBinding setCommandIdentifier:@"foo"]; 130 | 131 | [menuKeyBindingSet insertObject:cpKeyBinding inKeyBindingsAtIndex:0]; 132 | [menuKeyBindingSet updateDictionary]; 133 | } 134 | 135 | - (IDEKeyboardShortcut *)keyboardShortcutFromUserDefaults 136 | { 137 | return [IDEKeyboardShortcut keyboardShortcutFromStringRepresentation:[self keyBindingFromUserDefaults]]; 138 | } 139 | 140 | - (void)keyBindingsHaveChanged:(NSNotification *)notification 141 | { 142 | [self updateKeyBinding:[self currentUserCPKeyBinding] forMenuItem:self.menuItem defaultsKey:DEFAULTS_KEY_BINDING]; 143 | } 144 | 145 | - (void)updateKeyBinding:(IDEKeyBinding *)keyBinding forMenuItem:(NSMenuItem *)menuItem defaultsKey:(NSString *)defaultsKey 146 | { 147 | if ([[keyBinding keyboardShortcuts] count] > 0) { 148 | IDEKeyboardShortcut *keyboardShortcut = [[keyBinding keyboardShortcuts] objectAtIndex:0]; 149 | [self saveKeyBindingToUserDefaults:[keyboardShortcut stringRepresentation] forKey:defaultsKey]; 150 | [self updateMenuItem:menuItem withShortcut:keyboardShortcut]; 151 | } 152 | } 153 | 154 | - (void)updateMenuItem:(NSMenuItem *)menuItem withShortcut:(IDEKeyboardShortcut *)keyboardShortcut 155 | { 156 | [menuItem setKeyEquivalent:[keyboardShortcut keyEquivalent]]; 157 | [menuItem setKeyEquivalentModifierMask:[keyboardShortcut modifierMask]]; 158 | } 159 | 160 | // returns current key binding if it was customized by the user 161 | - (IDEKeyBinding *)currentUserCPKeyBinding 162 | { 163 | return [self menuKeyBindingWithItemTitle:CP_MENU_ITEM_TITLE underMenuCalled:CP_KEY_BINDING_MENU_NAME]; 164 | } 165 | 166 | - (IDEKeyBinding *)menuKeyBindingWithItemTitle:(NSString *)itemTitle underMenuCalled:(NSString *)menuName 167 | { 168 | IDEKeyBindingPreferenceSet *currentPreferenceSet = [[IDEKeyBindingPreferenceSet preferenceSetsManager] currentPreferenceSet]; 169 | IDEMenuKeyBindingSet *menuKeyBindingSet = [currentPreferenceSet menuKeyBindingSet]; 170 | 171 | for (IDEMenuKeyBinding *keyBinding in [menuKeyBindingSet keyBindings]) { 172 | if ([[keyBinding group] isEqualToString:menuName] && [[keyBinding title] isEqualToString:itemTitle]) { 173 | return keyBinding; 174 | } 175 | } 176 | 177 | return nil; 178 | } 179 | 180 | // installs "Code Pilot" menu item in "File" menu, 181 | // setting target and action on code pilot's window delegate 182 | - (void)installMenuItem 183 | { 184 | NSMenu *fileMenu = [[[[NSApp mainMenu] itemArray] objectAtIndex:1] submenu]; 185 | NSUInteger fileMenuItemCount = [[fileMenu itemArray] count]; 186 | 187 | [fileMenu insertItem:[NSMenuItem separatorItem] atIndex:fileMenuItemCount]; 188 | 189 | self.menuItem = [[NSMenuItem alloc] initWithTitle:CP_MENU_ITEM_TITLE 190 | action:@selector(openCodePilotWindow:) 191 | keyEquivalent:@""]; 192 | 193 | [self.menuItem setTarget:self.installedPlugin]; 194 | [self.menuItem setAction:@selector(openCodePilotWindow)]; 195 | 196 | [self updateMenuItem:self.menuItem withShortcut:[self keyboardShortcutFromUserDefaults]]; 197 | [fileMenu insertItem:self.menuItem atIndex:fileMenuItemCount + 1]; 198 | } 199 | 200 | // our preferences were applied/ok'd by the user 201 | - (void)preferencesDidChange 202 | { 203 | } 204 | 205 | - (void)dealloc 206 | { 207 | [self removeNotificationListeners]; 208 | } 209 | @end 210 | -------------------------------------------------------------------------------- /Classes/CPPreferencesToolbarDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CPPreferencesToolbarDelegate.m 3 | // CodePilot 4 | // 5 | // Created by Zbigniew Sobiecki on 4/23/11. 6 | // Copyright 2011 Macoscope. All rights reserved. 7 | // 8 | 9 | #import "CPPreferencesToolbarDelegate.h" 10 | #import "CPPreferencesViewController.h" 11 | #import "CPPreferencesView.h" 12 | 13 | static NSString * const SelectedItemIdentifierKeyPath = @"selectedItemIdentifier"; 14 | 15 | @interface CPPreferencesToolbarDelegate () 16 | @property (nonatomic, strong) IDEPreferencesController *originalDelegate; 17 | @property (nonatomic, strong) NSToolbarItem *ourToolbarItem; 18 | @property (nonatomic, strong) CPPreferencesViewController *ourViewController; 19 | 20 | @property (nonatomic, assign) CGFloat previousReplacementViewHeight; 21 | @property (nonatomic, strong) NSString *previousItemIdentifier; 22 | @end 23 | 24 | // this is kind of a proxy from IDEToolbar when used for preferences. 25 | // it passes all the messages defined in toolbar protocol to proper 26 | // object, adding custom items in the passing. 27 | @implementation CPPreferencesToolbarDelegate 28 | 29 | + (CPPreferencesToolbarDelegate *)preferencesToolbarDelegateByInterceptingDelegateOfToolbar:(NSToolbar *)toolbar 30 | { 31 | CPPreferencesToolbarDelegate *toolbarDelegate; 32 | IDEPreferencesController *originalToolbarDelegate = (IDEPreferencesController *)[toolbar delegate]; 33 | 34 | toolbarDelegate = [[CPPreferencesToolbarDelegate alloc] initWithOriginalToolbarDelegate:originalToolbarDelegate toolbar:toolbar]; 35 | 36 | [toolbar setDelegate:toolbarDelegate]; 37 | [toolbar insertItemWithItemIdentifier:PREFERENCES_TOOLBAR_ITEM_IDENTIFIER atIndex:toolbar.items.count]; 38 | 39 | return toolbarDelegate; 40 | } 41 | 42 | - (id)initWithOriginalToolbarDelegate:(IDEPreferencesController *)originalDelegate toolbar:(NSToolbar *)toolbar 43 | { 44 | self = [super init]; 45 | 46 | if (self) { 47 | self.originalDelegate = originalDelegate; 48 | 49 | [toolbar addObserver:self 50 | forKeyPath:SelectedItemIdentifierKeyPath 51 | options:NSKeyValueObservingOptionInitial 52 | context:nil]; 53 | 54 | self.ourViewController = [[CPPreferencesViewController alloc] init]; 55 | 56 | // apply changes in the controller 57 | [[NSNotificationCenter defaultCenter] addObserver:self.ourViewController 58 | selector:@selector(applyChanges) 59 | name:NSWindowWillCloseNotification 60 | object:self.originalDelegate.paneReplacementView.window]; 61 | 62 | [self prepareToolbarItem]; 63 | } 64 | 65 | return self; 66 | } 67 | 68 | - (void)dealloc 69 | { 70 | [[self.ourToolbarItem toolbar] removeObserver:self forKeyPath:SelectedItemIdentifierKeyPath]; 71 | [[self.ourToolbarItem toolbar] setDelegate:nil]; 72 | [[NSNotificationCenter defaultCenter] removeObserver:self.ourViewController]; 73 | } 74 | 75 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(NSToolbar *)toolbar change:(NSDictionary *)change context:(void *)context 76 | { 77 | // bring back the original replacement view, once we're out of Code Pilot pref pane 78 | DVTReplacementView *replacementView = [self.originalDelegate paneReplacementView]; 79 | NSWindow *window = [replacementView window]; 80 | 81 | if ([replacementView isHidden]) { 82 | [self.ourViewController applyChanges]; 83 | [self.ourViewController.view removeFromSuperview]; 84 | 85 | // The automatic resizing is only applied when the DVTExtension changes 86 | if ([self.previousItemIdentifier isEqualToString:[toolbar selectedItemIdentifier]]) { 87 | CGRect newWindowFrame = window.frame; 88 | newWindowFrame.size.height += self.previousReplacementViewHeight - self.ourViewController.view.frame.size.height; 89 | newWindowFrame.origin.y -= self.previousReplacementViewHeight - self.ourViewController.view.frame.size.height; 90 | 91 | [window setFrame:newWindowFrame display:YES animate:YES]; 92 | 93 | // To prevent the previous replacement subviews from being shown during the automatic resize animation 94 | } else { 95 | for (NSView *subview in [replacementView subviews]) { 96 | [subview removeFromSuperview]; 97 | } 98 | } 99 | 100 | [replacementView setHidden:NO]; 101 | } 102 | 103 | if (![[toolbar selectedItemIdentifier] isEqualToString:PREFERENCES_TOOLBAR_ITEM_IDENTIFIER]) { 104 | self.previousItemIdentifier = [toolbar selectedItemIdentifier]; 105 | } 106 | } 107 | 108 | - (void)prepareToolbarItem 109 | { 110 | self.ourToolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:PREFERENCES_TOOLBAR_ITEM_IDENTIFIER]; 111 | NSString *iconPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"CodePilotIcon" ofType:@"icns"]; 112 | NSImage *icon = [[NSImage alloc] initWithContentsOfFile:iconPath]; 113 | 114 | [self.ourToolbarItem setImage:icon]; 115 | [self.ourToolbarItem setLabel:PRODUCT_NAME]; 116 | [self.ourToolbarItem setPaletteLabel:PRODUCT_NAME]; 117 | [self.ourToolbarItem setEnabled:YES]; 118 | [self.ourToolbarItem setToolTip:PRODUCT_NAME]; 119 | [self.ourToolbarItem setTarget:self]; 120 | [self.ourToolbarItem setAction:@selector(ourItemWasSelected:)]; 121 | } 122 | 123 | - (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag 124 | { 125 | if ([itemIdentifier isEqualToString:[self.ourToolbarItem itemIdentifier]]) { 126 | return self.ourToolbarItem; 127 | } 128 | 129 | if (nil != self.originalDelegate && [self.originalDelegate respondsToSelector:@selector(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:)]) { 130 | return [self.originalDelegate toolbar:toolbar itemForItemIdentifier:itemIdentifier willBeInsertedIntoToolbar:flag]; 131 | } 132 | 133 | return nil; 134 | } 135 | 136 | - (void)ourItemWasSelected:(id)sender 137 | { 138 | DVTReplacementView *replacementView = [self.originalDelegate paneReplacementView]; 139 | NSWindow *window = [replacementView window]; 140 | 141 | self.previousReplacementViewHeight = replacementView.frame.size.height; 142 | 143 | CGRect newWindowFrame = window.frame; 144 | newWindowFrame.size.height -= replacementView.frame.size.height - self.ourViewController.view.frame.size.height; 145 | newWindowFrame.origin.y += replacementView.frame.size.height - self.ourViewController.view.frame.size.height; 146 | 147 | [window setTitle:PRODUCT_NAME]; 148 | [window setFrame:newWindowFrame display:YES animate:YES]; 149 | 150 | [replacementView setHidden:YES]; 151 | [self.ourViewController.view setFrame:(CGRect) {replacementView.frame.origin, CGSizeMake(replacementView.frame.size.width, [CPPreferencesView preferredHeight])}]; 152 | [[replacementView superview] addSubview:self.ourViewController.view]; 153 | } 154 | 155 | - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar 156 | { 157 | if (nil != self.originalDelegate && [self.originalDelegate respondsToSelector:@selector(toolbarAllowedItemIdentifiers:)]) { 158 | NSArray *itemIdentifiers = [self.originalDelegate toolbarAllowedItemIdentifiers:toolbar]; 159 | return [itemIdentifiers arrayByAddingObject:[self.ourToolbarItem itemIdentifier]]; 160 | } 161 | 162 | return nil; 163 | } 164 | 165 | - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar 166 | { 167 | if (nil != self.originalDelegate && [self.originalDelegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)]) { 168 | NSArray *itemIdentifiers = [self.originalDelegate toolbarDefaultItemIdentifiers:toolbar]; 169 | return [itemIdentifiers arrayByAddingObject:[self.ourToolbarItem itemIdentifier]]; 170 | } 171 | 172 | return nil; 173 | } 174 | 175 | 176 | - (void)toolbarDidRemoveItem:(NSNotification *)notification 177 | { 178 | if (nil != self.originalDelegate && [self.originalDelegate respondsToSelector:@selector(toolbarDidRemoveItem:)]) { 179 | [self.originalDelegate toolbarDidRemoveItem:notification]; 180 | } 181 | } 182 | 183 | 184 | - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar 185 | { 186 | if (nil != self.originalDelegate && [self.originalDelegate respondsToSelector:@selector(toolbarSelectableItemIdentifiers:)]) { 187 | NSArray *itemIdentifiers = [self.originalDelegate toolbarSelectableItemIdentifiers:toolbar]; 188 | return [itemIdentifiers arrayByAddingObject:[self.ourToolbarItem itemIdentifier]]; 189 | } 190 | 191 | return nil; 192 | } 193 | 194 | 195 | - (void)toolbarWillAddItem:(NSNotification *)notification 196 | { 197 | if (nil != self.originalDelegate && [self.originalDelegate respondsToSelector:@selector(toolbarWillAddItem:)]) { 198 | [self.originalDelegate toolbarWillAddItem:notification]; 199 | } 200 | } 201 | @end -------------------------------------------------------------------------------- /Classes/CPCodePilotConfig.h: -------------------------------------------------------------------------------- 1 | 2 | // this is general config used for every xcode version we support. 3 | 4 | #import 5 | #import "MCCommons.h" 6 | #import "MCLog.h" 7 | #import 8 | #import 9 | #import "CPCodePilotPlugin.h" 10 | #import "NSView+AllSubviews.h" 11 | #import "NSString+Abbreviation.h" 12 | #import "CPCodePilotWindowDelegate.h" 13 | #import "NSNumber+VersionComparison.h" 14 | 15 | #undef DEBUG_MODE 16 | 17 | #define XCODE_VERSION_CHECKING_DISABLED 1 18 | 19 | #define PRODUCT_NAME @"Code Pilot" 20 | #define PRODUCT_NAME_FOR_UPDATES @"codepilot3" 21 | #define PREFERENCES_TOOLBAR_ITEM_IDENTIFIER @"codepilot3" 22 | #define PRODUCT_CURRENT_VERSION [[[NSBundle bundleForClass:NSClassFromString(@"CPCodePilotPlugin")] infoDictionary] valueForKey:@"CFBundleShortVersionString"] 23 | 24 | 25 | #define CP_MENU_ITEM_TITLE PRODUCT_NAME 26 | #define CP_DEFAULT_SHORTCUT @"$@X" // for key binding system 27 | #define CP_DEFAULT_MENU_SHORTCUT @"X" // just for the menuitem 28 | #define CP_KEY_BINDING_MENU_NAME @"File Menu" 29 | 30 | #define DEFAULT_KEY_EQUIVALENT @"X" 31 | 32 | #define MAX_OBJECT_COUNT_FOR_SORT_AND_FILTER 4989 33 | 34 | #define DOCUMENTATION_MODE [[CPCodePilotPlugin sharedInstance] isInDocumentationMode] 35 | 36 | #define NO_PROJECT_OPEN_INFO_STRING [NSString stringWithFormat:@"%@ %@ works with projects only.\n\nOpen some project first!", PRODUCT_NAME, PRODUCT_CURRENT_VERSION] 37 | #define CURRENT_XCODE_VERSION_UNSUPPORTED_INFO_STRING [NSString stringWithFormat:@"Xcode %@ isn't supported in %@ %@.\n\nClick here to upgrade!", CURRENT_XCODE_VERSION_STRING, PRODUCT_NAME, PRODUCT_CURRENT_VERSION] 38 | #define FIRST_RUN_INFO_STRING [NSString stringWithFormat:@"Thanks for installing %@ %@!\nOpen some project and press \u21d1\u2318X to start!", PRODUCT_NAME, PRODUCT_CURRENT_VERSION] 39 | #define TOO_MANY_RESULTS_STRING @"Gosh, so many results! Please try to be more specific." 40 | 41 | #define CURRENT_XCODE_VERSION_STRING [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"] 42 | #define CURRENT_XCODE_VERSION [NSNumber numberWithVersionString:CURRENT_XCODE_VERSION_STRING] 43 | #define CURRENT_XCODE_REVISION [NSNumber numberWithVersionNumber:[[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleVersion"]] 44 | 45 | #define NO_PROJECT_IS_CURRENTLY_OPEN (![[[CPCodePilotPlugin sharedInstance] xcWrapper] hasOpenWorkspace]) 46 | 47 | #define PRODUCT_BUY_LINK @"http://codepilot.cc" 48 | 49 | 50 | #define CREDITS_STRING @"AMIndeterminateProgressIndicatorCell - Copyright © 2007 Andreas Mayer\nQSSmallScroller - Copyright © 2007-2008 Google Inc. All rights reserved\nRegexKitLite - Copyright © 2008-2009 John Engelhart" 51 | #define THANKS_STRING @"Ruben Bakker, Marcus S. Zarra"; 52 | 53 | #define PILOT_WINDOW_DELEGATE (CPCodePilotWindowDelegate *)[[CPCodePilotPlugin sharedInstance] windowDelegate] 54 | #define USER_LEVEL_DEBUG [[CPCodePilotPlugin sharedInstance] isUserLevelDebugOn] 55 | #define OUR_WINDOW_IS_OPEN [PILOT_WINDOW_DELEGATE ourWindowIsOpen] 56 | 57 | 58 | #define CORNER_RADIUS 20 59 | #define BACKGROUND_COLOR [NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.851] 60 | 61 | #define FILE_SELECTION_CELL_FONT_NAME @"Helvetica" 62 | #define FILE_SELECTION_CELL_FONT_SIZE 18 63 | 64 | #define SYMBOL_SELECTION_CELL_FONT_NAME FILE_SELECTION_CELL_FONT_NAME 65 | #define SYMBOL_SELECTION_CELL_FONT_SIZE FILE_SELECTION_CELL_FONT_SIZE 66 | 67 | #define SYMBOL_SELECTION_CELL_EXTENDED_INFO_FONT_NAME @"Monaco" 68 | #define SYMBOL_SELECTION_CELL_EXTENDED_INFO_FONT_SIZE 12 69 | 70 | #define FILE_SELECTION_CELL_EXTENDED_INFO_FONT_NAME @"Monaco" 71 | #define FILE_SELECTION_CELL_EXTENDED_INFO_FONT_SIZE 12 72 | #define FILE_SELECTION_CELL_FONT_COLOR [NSColor colorWithCalibratedWhite:0.657 alpha:1.000] 73 | #define FILE_SELECTION_CELL_HIGHLIGHTED_FONT_COLOR [NSColor whiteColor] 74 | 75 | #define FILE_SELECTION_CELL_HEIGHT FILE_SELECTION_CELL_FONT_SIZE*1.7 76 | #define SYMBOL_SELECTION_CELL_HEIGHT SYMBOL_SELECTION_CELL_FONT_SIZE*1.7 77 | 78 | #define SYMBOL_SELECTION_CELL_EXTENDED_HEIGHT (SYMBOL_SELECTION_CELL_FONT_SIZE+SYMBOL_SELECTION_CELL_EXTENDED_INFO_FONT_SIZE)*1.7 79 | #define SYMBOL_SELECTION_CELL_EXTENDED_INFO_COLOR [NSColor lightGrayColor] 80 | #define SYMBOL_SELECTION_CELL_HIGHLIGHTED_EXTENDED_INFO_COLOR [NSColor whiteColor] 81 | 82 | #define FILE_SELECTION_CELL_EXTENDED_HEIGHT (FILE_SELECTION_CELL_FONT_SIZE+FILE_SELECTION_CELL_EXTENDED_INFO_FONT_SIZE)*1.7 83 | #define FILE_SELECTION_CELL_EXTENDED_INFO_COLOR [NSColor lightGrayColor] 84 | 85 | // how far from the top the window will be located 86 | // 0.2 means - 1/5 of screensize from the menu bar. 87 | #define WINDOW_TOP_LOCATION_ON_THE_SCREEN 0.2 88 | 89 | // more defined in cpsearchwindowview.h 90 | #define WINDOW_WIDTH 500.0f 91 | #define WINDOW_MARGIN 10.0f 92 | #define PROGRESS_INDICATOR_HEIGHT 15.0f 93 | #define PROGRESS_INDICATOR_WIDTH 15.0f 94 | #define PROGRESS_INDICATOR_RIGHT_MARGIN 15.0f 95 | 96 | #define WINDOW_CONTROL_WIDTH (WINDOW_WIDTH-(2*WINDOW_MARGIN)) 97 | 98 | #define MAX_TABLE_HEIGHT 400.0f 99 | 100 | #define WINDOW_INFO_LABEL_UNREGISTERED_FONT_COLOR [NSColor lightGrayColor] 101 | #define WINDOW_INFO_LABEL_NEW_VERSION_AVAILABLE_FONT_COLOR [NSColor whiteColor] 102 | 103 | #define SYMBOL_OTHER_NAME_COLOR [NSColor lightGrayColor] 104 | 105 | #define TABLE_ROW_HIGHLIGHT_COLOR [NSColor colorWithDeviceWhite:0.25 alpha:0.95] 106 | 107 | #define RESULT_CELL_FILE_ICON_WIDTH 35.0f 108 | #define RESULT_CELL_FILE_EXTENDED_ICON_WIDTH 55.0f 109 | #define RESULT_CELL_SYMBOL_ICON_WIDTH RESULT_CELL_FILE_ICON_WIDTH + 3 110 | #define RESULT_CELL_SYMBOL_EXTENDED_ICON_WIDTH RESULT_CELL_FILE_EXTENDED_ICON_WIDTH + 2 111 | #define RESULT_CELL_ICON_LEFT_MARGIN 9.0f 112 | 113 | #define SEARCHFIELD_FONT @"Lucida Grande" 114 | #define SEARCHFIELD_FONT_SIZE 18 115 | #define SEARCHFIELD_FONT_COLOR [NSColor whiteColor] 116 | #define SEARCHFIELD_TOKEN_FONT @"Lucida Grande" 117 | #define SEARCHFIELD_TOKEN_CORNER_RADIUS 10 118 | #define SEARCHFIELD_TOKEN_FONT_SIZE 18 119 | #define SEARCHFIELD_TOKEN_FONT_COLOR [NSColor colorWithCalibratedRed:0.221 green:0.221 blue:0.22 alpha:1.000] 120 | #define SEARCHFIELD_TOKEN_BACKGROUND_COLOR [NSColor colorWithCalibratedRed:0.654 green:0.654 blue:0.654 alpha:1.000] 121 | #define SEARCHFIELD_TOKEN_BORDER_COLOR [NSColor colorWithCalibratedRed:0.523 green:0.523 blue:0.523 alpha:1.000] 122 | #define SEARCHFIELD_TOKEN_INSIDE_MARGIN 4 123 | 124 | #define SEARCHFIELD_PLACEHOLDER_STRING @"Type your query to find files and symbols" 125 | #define SEARCHFIELD_PLACEHOLDER_FONT_SIZE 16 126 | #define SEARCHFIELD_PLACEHOLDER_FONT @"Helvetica" // Grande version doesn't have native italic version 127 | #define SEARCHFIELD_PLACEHOLDER_ALTERNATIVE_FONT @"Lucida Grande" // Lucida Grande isn't supported on fresh systems 128 | #define SEARCHFIELD_PLACEHOLDER_FONT_COLOR [NSColor colorWithCalibratedRed:0.631 green:0.631 blue:0.631 alpha:0.75] 129 | 130 | #define DEFAULT_SEARCHFIELD_DELAY_VALUE 0.4 131 | 132 | // how often do we check whether index is ready and if we need to reload symbol table 133 | #define INDEX_STATE_CHECK_INTERVAL 0.5 134 | 135 | // #define PRESERVE_SELECTION 1 136 | 137 | #define MCXcodeWrapperReloadedIndex @"__MCXcodeWrapperReloadedIndex" 138 | 139 | // Preferences - system fonts are used here 140 | #define PREFS_CREDITS_TEXT_FONT_SIZE 11 141 | 142 | #define PREFS_VIEW_MIN_WIDTH 630 143 | #define PREFS_VIEW_MIN_HEIGHT 230 144 | 145 | #define DEFAULTS_AUTOCOPY_SELECTION_KEY @"MCCodePilotAutocopySelection" 146 | #define DEFAULTS_EXTERNAL_EDITOR_KEY @"MCCodePilotUseExternalEditor" 147 | #define DEFAULTS_API_SEARCH_KEY @"MCCodePilotAPISearch" 148 | #define DEFAULTS_LAST_VERSION_RUN_KEY @"MCCodePilotLastVersionRun" 149 | #define DEFAULTS_USER_LEVEL_DEBUG_KEY @"MCCodePilotUserLevelDebug" 150 | #define DEFAULTS_SEARCH_INTERVAL_KEY @"MCCodePilotSearchFieldDelay" // in seconds 151 | #define DEFAULTS_INCLUDE_SUBPROJECTS_KEY @"MCCodePilotIncludeSubprojects" 152 | #define DEFAULTS_KEY_BINDING @"MCCodePilotKeyBinding" 153 | 154 | #define DEFAULT_INCLUDE_SUBPROJECTS_VALUE NO 155 | #define DEFAULT_AUTOCOPY_SELECTION_VALUE NO 156 | #define DEFAULT_EXTERNAL_EDITOR_SELECTION_VALUE NO 157 | #define DEFAULT_API_SEARCH_VALUE YES 158 | 159 | // longest string we accept in autocopying from current editor's selection 160 | #define MAX_AUTOCOPY_STRING_LENGTH 100 161 | 162 | #define IS_THIS_NEW_VERSION_FIRST_RUN [[CPCodePilotPlugin sharedInstance] thisVersionFirstRun] 163 | #define IS_THIS_FIRST_RUN_EVER [[CPCodePilotPlugin sharedInstance] firstRunEver] 164 | 165 | #define INFO_WINDOW_WIDTH 360 166 | #define INFO_WINDOW_HEIGHT 133 167 | 168 | #define __OPEN_CODE_PILOT_WINDOW @"openCodePilotWindow" 169 | 170 | #define USER_LOG(s, ...) do{if(USER_LEVEL_DEBUG){[MCLog prefix:[NSString stringWithFormat:@"%@ %@", PRODUCT_NAME, PRODUCT_CURRENT_VERSION] format:(s),##__VA_ARGS__];}}while(0) 171 | 172 | #define LOG_TIMESTAMP_SINCE(msg, ddd) NSLog([NSString stringWithFormat:@"[TS] %0.2fs %@", [[NSDate date] timeIntervalSinceDate:ddd], msg]) 173 | --------------------------------------------------------------------------------