diff --git a/app/CPReflectionService/CPReflectionService.m b/app/CPReflectionService/CPReflectionService.m index 1ae1313d..e27e81ba 100644 --- a/app/CPReflectionService/CPReflectionService.m +++ b/app/CPReflectionService/CPReflectionService.m @@ -52,4 +52,13 @@ - (void)XcodeIntegrationInformationFromPodfile:(NSString * _Nonnull)contents } +- (void)allPods:(void (^ _Nonnull)(NSArray * _Nullable pods, NSError * _Nullable error))reply +{ + [RBObject performBlock:^{ + reply([RBObjectFromString(@"Pod::App") all_pods], nil); + } error:^(NSError * _Nonnull error) { + reply(nil, error); + }]; +} + @end diff --git a/app/CPReflectionService/CPReflectionServiceProtocol.h b/app/CPReflectionService/CPReflectionServiceProtocol.h index dfc86f0a..ff2192a6 100644 --- a/app/CPReflectionService/CPReflectionServiceProtocol.h +++ b/app/CPReflectionService/CPReflectionServiceProtocol.h @@ -12,4 +12,6 @@ - (void)pluginsFromPodfile:(NSString * _Nonnull)contents withReply:(void (^ _Nonnull)(NSArray * _Nullable plugins, NSError * _Nullable error))reply; +- (void)allPods:(void (^ _Nonnull)(NSArray * _Nullable pods, NSError * _Nullable error))reply; + @end diff --git a/app/CPReflectionService/RBObject+CocoaPods.h b/app/CPReflectionService/RBObject+CocoaPods.h index ba9c8a56..fe4354f8 100644 --- a/app/CPReflectionService/RBObject+CocoaPods.h +++ b/app/CPReflectionService/RBObject+CocoaPods.h @@ -48,4 +48,6 @@ typedef void (^RBObjectErrorBlock)(NSError * _Nonnull error); @interface RBApp : RBObject - (void)require_gems; - (NSDictionary * _Nonnull)analyze_podfile:(RBPodfile * _Nonnull)contents :(NSString * _Nonnull)installationRoot; +- (NSArray * _Nullable)all_pods; @end + diff --git a/app/CPReflectionService/RBObject+CocoaPods.rb b/app/CPReflectionService/RBObject+CocoaPods.rb index d78ac2ee..f84277ac 100644 --- a/app/CPReflectionService/RBObject+CocoaPods.rb +++ b/app/CPReflectionService/RBObject+CocoaPods.rb @@ -1,3 +1,5 @@ +Encoding.default_external = 'UTF-8' + # This is required for Foundation classes to be known to this side of the bridge at all. require 'osx/objc/foundation' @@ -58,5 +60,9 @@ def self.analyze_podfile(podfile, installation_root) uses_frameworks = config.podfile.target_definitions.first.last.to_hash["uses_frameworks"] { "projects" => user_projects, "pod_targets" => pod_targets, "uses_frameworks" => uses_frameworks} end + + def self.all_pods + Pod::SourcesManager.aggregate.all_pods + end end end \ No newline at end of file diff --git a/app/CocoaPods.xcodeproj/project.pbxproj b/app/CocoaPods.xcodeproj/project.pbxproj index 96c461aa..b773fe67 100644 --- a/app/CocoaPods.xcodeproj/project.pbxproj +++ b/app/CocoaPods.xcodeproj/project.pbxproj @@ -78,6 +78,7 @@ 770382F41A2035B400435285 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 770382F31A2035B400435285 /* Localizable.strings */; }; 77356D751A2253F1002822CF /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 77356D741A2253F1002822CF /* Media.xcassets */; }; 7C4B007D1B9B441800B6C782 /* CPANSIEscapeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C4B007C1B9B441800B6C782 /* CPANSIEscapeHelper.m */; }; + E70998471C49AB5B00229507 /* Podfile.plist in Resources */ = {isa = PBXBuildFile; fileRef = E70998461C49AB5B00229507 /* Podfile.plist */; }; FA16FAD21C144BF300DC3791 /* URLHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA16FAD11C144BF300DC3791 /* URLHandler.swift */; }; FCDCC48F0E8CE099C20D1DEB /* Pods_CocoaPodsTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 62FB6E124C8280A7EBFD41C6 /* Pods_CocoaPodsTests.framework */; }; /* End PBXBuildFile section */ @@ -249,6 +250,7 @@ 77356D741A2253F1002822CF /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = ""; }; 7C4B007B1B9B441800B6C782 /* CPANSIEscapeHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPANSIEscapeHelper.h; sourceTree = ""; }; 7C4B007C1B9B441800B6C782 /* CPANSIEscapeHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPANSIEscapeHelper.m; sourceTree = ""; }; + E70998461C49AB5B00229507 /* Podfile.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Podfile.plist; path = "Syntax Definitions/Podfile.plist"; sourceTree = ""; }; EBD9373107B77CCDFCD43B67 /* Pods-CocoaPods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CocoaPods.release.xcconfig"; path = "Pods/Target Support Files/Pods-CocoaPods/Pods-CocoaPods.release.xcconfig"; sourceTree = ""; }; EEB7DFACCFDF9B3B443AF311 /* Pods_CocoaPods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CocoaPods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FA16FAD11C144BF300DC3791 /* URLHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLHandler.swift; sourceTree = ""; }; @@ -389,6 +391,7 @@ isa = PBXGroup; children = ( 5180FE931AD2A51300314D61 /* LICENSE */, + E70998461C49AB5B00229507 /* Podfile.plist */, 77356D741A2253F1002822CF /* Media.xcassets */, 51D2E5AF1A212A0800C0B153 /* Syntax Definitions */, 51D2E5B01A212A0800C0B153 /* SyntaxDefinitions.plist */, @@ -741,6 +744,7 @@ 51165E2D1A17AFF500DCFC94 /* MainMenu.xib in Resources */, 51D2E5B11A212A0800C0B153 /* Syntax Definitions in Resources */, 606D1ED21BF90705000B7148 /* Podfile.storyboard in Resources */, + E70998471C49AB5B00229507 /* Podfile.plist in Resources */, 6075BA651C068B5F00A5C491 /* Podfile.xcassets in Resources */, 6033ECB21C1E6B4D00C2EDAD /* Home Screen.xcassets in Resources */, 5180FE941AD2A51300314D61 /* LICENSE in Resources */, diff --git a/app/CocoaPods/CPPodfileEditorViewController.swift b/app/CocoaPods/CPPodfileEditorViewController.swift index 351adcc4..44606010 100644 --- a/app/CocoaPods/CPPodfileEditorViewController.swift +++ b/app/CocoaPods/CPPodfileEditorViewController.swift @@ -5,12 +5,30 @@ import Fragaria /// and ensure the changes are sent back upstream to the /// CPPodfileViewController's CPUserProject -class CPPodfileEditorViewController: NSViewController, NSTextViewDelegate { +class CPPodfileEditorViewController: NSViewController, NSTextViewDelegate, SMLAutoCompleteDelegate { @IBOutlet var editor: MGSFragariaView! var syntaxChecker: CPPodfileReflection! let commentSyntax = "# " let indentationSyntax = " " + var autoCompletions: [String] = { + if let path = NSBundle.mainBundle().pathForResource("Podfile", ofType: "plist"), + dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject], + words = dict["autocompleteWords"] as? [String] { + return words + } + return [] + }() + + override func viewDidLoad() { + super.viewDidLoad() + let appDelegate = NSApp.delegate as? CPAppDelegate + appDelegate?.reflectionService.remoteObjectProxy.allPods { (pods, error) in + if let pods = pods { + self.autoCompletions.appendContentsOf(pods) + } + } + } // As the userProject is DI'd into the PodfileVC // it occurs after the view is set up. @@ -34,6 +52,7 @@ class CPPodfileEditorViewController: NSViewController, NSTextViewDelegate { editor.colourForKeywords = settings.cpBlue editor.colourForVariables = settings.cpGreen editor.colourForInstructions = settings.cpBrightMagenta + editor.autoCompleteDelegate = self editor.tabWidth = 2 editor.indentWithSpaces = true @@ -44,6 +63,10 @@ class CPPodfileEditorViewController: NSViewController, NSTextViewDelegate { syntaxChecker.textDidChange(NSNotification(name: "", object: nil)) } + func completions() -> [AnyObject]! { + return autoCompletions + } + func textDidChange(notification: NSNotification) { guard let textView = notification.object as? NSTextView, let podfileVC = podfileViewController else { return }