├── Source ├── Swift Demangle.lbaction │ └── Contents │ │ ├── _CodeSignature │ │ ├── CodeTopDirectory │ │ ├── CodeRequirements │ │ └── CodeResources │ │ ├── Resources │ │ └── Swift Logo.pdf │ │ ├── Scripts │ │ └── default.sh │ │ └── Info.plist ├── Search OSStatus Icons.sketch ├── Search OSStatus.lbaction │ └── Contents │ │ ├── Resources │ │ ├── OS X.png │ │ ├── iOS.png │ │ ├── tvOS.png │ │ ├── OS X@2x.png │ │ ├── iOS@2x.png │ │ ├── tvOS@2x.png │ │ ├── watchOS.png │ │ ├── OS X & iOS.png │ │ ├── watchOS@2x.png │ │ └── OS X & iOS@2x.png │ │ ├── Info.plist │ │ └── Scripts │ │ └── default.js ├── Create New Swift Playground (OS X).lbaction │ └── Contents │ │ ├── Resources │ │ └── Template.playground │ │ │ ├── Contents.swift │ │ │ ├── contents.xcplayground │ │ │ └── playground.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ ├── Info.plist │ │ └── Scripts │ │ └── default.swift └── Create New Swift Playground (iOS).lbaction │ └── Contents │ ├── Resources │ └── Template.playground │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata │ ├── Info.plist │ └── Scripts │ └── default.swift ├── Signed Actions ├── Search OSStatus.lbaction ├── Swift Demangle.lbaction ├── Create New Swift Playground (iOS).lbaction └── Create New Swift Playground (OS X).lbaction └── README.md /Source/Swift Demangle.lbaction/Contents/_CodeSignature/CodeTopDirectory: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /Source/Search OSStatus Icons.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus Icons.sketch -------------------------------------------------------------------------------- /Signed Actions/Search OSStatus.lbaction: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Signed Actions/Search OSStatus.lbaction -------------------------------------------------------------------------------- /Signed Actions/Swift Demangle.lbaction: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Signed Actions/Swift Demangle.lbaction -------------------------------------------------------------------------------- /Signed Actions/Create New Swift Playground (iOS).lbaction: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Signed Actions/Create New Swift Playground (iOS).lbaction -------------------------------------------------------------------------------- /Signed Actions/Create New Swift Playground (OS X).lbaction: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Signed Actions/Create New Swift Playground (OS X).lbaction -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/OS X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/OS X.png -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/iOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/iOS.png -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/tvOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/tvOS.png -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/OS X@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/OS X@2x.png -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/iOS@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/iOS@2x.png -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/tvOS@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/tvOS@2x.png -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/watchOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/watchOS.png -------------------------------------------------------------------------------- /Source/Swift Demangle.lbaction/Contents/Resources/Swift Logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Swift Demangle.lbaction/Contents/Resources/Swift Logo.pdf -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/OS X & iOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/OS X & iOS.png -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/watchOS@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/watchOS@2x.png -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Resources/OS X & iOS@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Search OSStatus.lbaction/Contents/Resources/OS X & iOS@2x.png -------------------------------------------------------------------------------- /Source/Swift Demangle.lbaction/Contents/_CodeSignature/CodeRequirements: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcomasser/LaunchBarActions/HEAD/Source/Swift Demangle.lbaction/Contents/_CodeSignature/CodeRequirements -------------------------------------------------------------------------------- /Source/Create New Swift Playground (OS X).lbaction/Contents/Resources/Template.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import Cocoa 4 | 5 | var str = "Hello, playground" 6 | -------------------------------------------------------------------------------- /Source/Create New Swift Playground (iOS).lbaction/Contents/Resources/Template.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | -------------------------------------------------------------------------------- /Source/Create New Swift Playground (OS X).lbaction/Contents/Resources/Template.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Source/Create New Swift Playground (iOS).lbaction/Contents/Resources/Template.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Source/Create New Swift Playground (OS X).lbaction/Contents/Resources/Template.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Source/Create New Swift Playground (iOS).lbaction/Contents/Resources/Template.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Source/Swift Demangle.lbaction/Contents/Scripts/default.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # LaunchBar Action Script 4 | # 5 | 6 | # Check for empty string because swift-demangle would 7 | # then enter an interactive mode, which we dont want: 8 | if [ -z $1 ]; then 9 | exit 10 | fi 11 | 12 | xcrun swift-demangle -compact $@ 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LaunchBar Actions 2 | ================= 3 | 4 | # Search OSStatus 5 | 6 | This action uses [osstatus.com](http://www.osstatus.com) to look up information about error codes on Apple’s platforms. This is useful if you’re a developer who wants to look up some error code or constant but you don’t know in which framework or in which header it is defined. 7 | 8 | As a bonus, if you have Xcode installed (either as /Applications/Xcode.app or /Applications/Xcode-beta.app), the search results let you browse the related frameworks and header files directly in the respective SDK. 9 | 10 | 11 | # Create New Swift Playground 12 | 13 | Oftentimes, I just want to try something out in a clean Playground, but switching to Xcode, creating a new Playground and (most importantly) then deciding how to name it and where to save it is just no fun for me. 14 | 15 | That’s why I wrote a LaunchBar Action that just creates a new Playground and opens it right away. You can optionally enter a name for the Playground, but you don’t have to (a timestamped name is used by default). 16 | 17 | It’s written in Swift 2.2, so Xcode 7.3 is required. 18 | 19 | 20 | # Swift Demangle 21 | 22 | Uses “xcrun swift-demangle” to convert a mangled Swift symbol name to a human-readable Swift symbol name. Handy for quickly selecting some mangled symbol and sending it to LaunchBar via Instant Send, then demangling the symbol. 23 | 24 | Here’s a mangled name for you to try: __TFCCC4test1a1b1c1dfS2_FTS0_1xS1_1vFT1xSi_Si_OVS_1e1f 25 | 26 | For more information, read Mike Ash’s post on [Swift Name Mangling](https://mikeash.com/pyblog/friday-qa-2014-08-15-swift-name-mangling.html). 27 | -------------------------------------------------------------------------------- /Source/Create New Swift Playground (iOS).lbaction/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIconFile 6 | com.apple.dt.Xcode:playground_Icon.icns 7 | CFBundleIdentifier 8 | com.duckcode.LaunchBar.action.CreateNewSwiftPlayground.iOS 9 | CFBundleName 10 | Create New Swift Playground (iOS) 11 | CFBundleVersion 12 | 1.6 13 | NSHumanReadableCopyright 14 | Copyright © 2014-2015 Marco Masser 15 | LBTextInputTitle 16 | New Playground Name 17 | LBScripts 18 | 19 | LBDefaultScript 20 | 21 | LBScriptName 22 | default.swift 23 | LBAcceptedArgumentTypes 24 | 25 | string 26 | 27 | LBReturnsResult 28 | 29 | LBResultType 30 | path 31 | 32 | 33 | LBDescription 34 | 35 | LBAuthor 36 | Marco Masser 37 | LBWebsiteURL 38 | https://github.com/marcomasser/LaunchBarActions 39 | LBTwitter 40 | @ogott 41 | LBSummary 42 | This action creates a new Swift Playground for iOS and opens it. 43 | By default, the new Playground will be created in the Documents directory, but that can be changed in the Action’s preferences file after it is run for the first time. 44 | LBRequirements 45 | This action is written in Swift 2.2 and therefore requires Xcode 7.3. 46 | LBArgument 47 | The name for the new Playground. If omitted, a timestamped name will be used. 48 | LBResult 49 | If ⇧ is held down, selects the new Playground in LaunchBar. Otherwise, the new Playground is opened and nothing is returned. 50 | LBDownloadURL 51 | https://github.com/marcomasser/LaunchBarActions/raw/master/Signed%20Actions/Create%20New%20Swift%20Playground%20(iOS).lbaction 52 | LBUpdateURL 53 | https://github.com/marcomasser/LaunchBarActions/raw/master/Source/Create%20New%20Swift%20Playground%20(iOS).lbaction/Contents/Info.plist 54 | LBChangelog 55 | Version 1.4: Added support for updating the Action. 56 | Version 1.5: Updated to Swift 2.2. 57 | Version 1.6: Updated Playground template files. 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Source/Create New Swift Playground (OS X).lbaction/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIconFile 6 | com.apple.dt.Xcode:playground_Icon.icns 7 | CFBundleIdentifier 8 | com.duckcode.LaunchBar.action.CreateNewSwiftPlayground 9 | CFBundleName 10 | Create New Swift Playground (OS X) 11 | CFBundleVersion 12 | 1.6 13 | NSHumanReadableCopyright 14 | Copyright © 2014-2016 Marco Masser 15 | LBTextInputTitle 16 | New Playground Name 17 | LBScripts 18 | 19 | LBDefaultScript 20 | 21 | LBScriptName 22 | default.swift 23 | LBAcceptedArgumentTypes 24 | 25 | string 26 | 27 | LBReturnsResult 28 | 29 | LBResultType 30 | path 31 | 32 | 33 | LBDescription 34 | 35 | LBAuthor 36 | Marco Masser 37 | LBWebsiteURL 38 | https://github.com/marcomasser/LaunchBarActions 39 | LBTwitter 40 | @ogott 41 | LBSummary 42 | This action creates a new Swift Playground for OS X and opens it. 43 | By default, the new Playground will be created in the Documents directory, but that can be changed in the Action’s preferences file after it is run for the first time. 44 | LBRequirements 45 | This action is written in Swift 2.2 and therefore requires Xcode 7.3. 46 | LBArgument 47 | The name for the new Playground. If omitted, a timestamped name will be used. 48 | LBResult 49 | If ⇧ is held down, selects the new Playground in LaunchBar. Otherwise, the new Playground is opened and nothing is returned. 50 | LBDownloadURL 51 | https://github.com/marcomasser/LaunchBarActions/raw/master/Signed%20Actions/Create%20New%20Swift%20Playground%20(OS%20X).lbaction 52 | LBUpdateURL 53 | https://github.com/marcomasser/LaunchBarActions/raw/master/Source/Create%20New%20Swift%20Playground%20(OS%20X).lbaction/Contents/Info.plist 54 | LBChangelog 55 | Version 1.4: Added support for updating the Action. 56 | Version 1.5: Updated to Swift 2.2. 57 | Version 1.6: Updated Playground template files. 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Source/Swift Demangle.lbaction/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIconFile 6 | Swift Logo.pdf 7 | CFBundleIdentifier 8 | com.duckcode.LaunchBar.action.SwiftDemangle 9 | CFBundleName 10 | Swift Demangle 11 | CFBundleVersion 12 | 1.0 13 | LBArgument 14 | A mangled Swift symbol name. 15 | LBDescription 16 | 17 | LBArgument 18 | A mangled Swift symbol name. 19 | LBAuthor 20 | Marco Masser 21 | LBEmail 22 | marco@duckcode.com 23 | LBRequirements 24 | xcrun must point to a Swift-compatible version of Xcode. 25 | LBResult 26 | A demangled Swift symbol name. 27 | LBSummary 28 | Uses “xcrun swift-demangle” to convert a mangled Swift symbol name to a human-readable Swift symbol name. Handy for quickly selecting some mangled symbol and sending it to LaunchBar via Instant Send, then demangling the symbol. 29 | LBTwitter 30 | @ogott 31 | LBWebsiteURL 32 | https://github.com/marcomasser/LaunchBarActions 33 | LBUpdateURL 34 | https://github.com/marcomasser/LaunchBarActions/raw/master/Source/Swift%20Demangle.lbaction/Contents/Info.plist 35 | LBDownloadURL 36 | https://github.com/marcomasser/LaunchBarActions/raw/master/Signed%20Actions/Swift%20Demangle.lbaction 37 | LBChangelog 38 | 1.0: Initial Release. 39 | 40 | LBRequiredApplication 41 | com.apple.dt.Xcode 42 | LBRequirements 43 | Uses “xcrun swift-demangle” and therefore requires xcrun to point to a Swift-compatible version of Xcode. 44 | LBResult 45 | A demangled Swift symbol name. 46 | LBScripts 47 | 48 | LBDefaultScript 49 | 50 | LBAcceptedArgumentTypes 51 | 52 | string 53 | 54 | LBKeepWindowActive 55 | 56 | LBRequiresArgument 57 | 58 | LBResultType 59 | string 60 | LBReturnsResult 61 | 62 | LBScriptName 63 | default.sh 64 | 65 | 66 | LBTextInputTitle 67 | Mangled Name 68 | NSHumanReadableCopyright 69 | © 2016 Marco Masser, Swift and the Swift logo are trademarks of Apple Inc. 70 | 71 | 72 | -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIconFile 6 | /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertStopIcon.icns 7 | CFBundleIdentifier 8 | com.duckcode.LaunchBar.action.SearchOSStatus 9 | CFBundleName 10 | Search OSStatus 11 | CFBundleVersion 12 | 1.0.1 13 | LBAbbreviation 14 | err 15 | LBArgument 16 | An error name, code (integer, OSType, hex, or string), framework name, or header file 17 | LBDescription 18 | 19 | LBArgument 20 | An error name, code (integer, OSType, hex, or string), framework name, or header file 21 | LBAuthor 22 | Marco Masser 23 | LBEmail 24 | marco@duckcode.com 25 | LBRequirements 26 | Requires an internet connection. If Xcode is installed (as /Applications/Xcode.app or /Applications/Xcode-beta.app), the result items contain a reference to the header file that defines the error in the respective SDK. 27 | LBResult 28 | A list of matching errors. 29 | LBSummary 30 | Look up Apple API errors fast! Powered by osstatus.com 31 | LBTwitter 32 | @ogott 33 | LBWebsiteURL 34 | https://github.com/marcomasser/LaunchBarActions 35 | LBUpdateURL 36 | https://github.com/marcomasser/LaunchBarActions/raw/master/Source/Search%20OSStatus.lbaction/Contents/Info.plist 37 | LBDownloadURL 38 | https://github.com/marcomasser/LaunchBarActions/raw/master/Signed%20Actions/Search%20OSStatus.lbaction 39 | LBChangelog 40 | 1.0: Initial Release. 41 | 1.0.1: Fixed paths for tvOS SDK. 42 | 43 | LBRequirements 44 | Requires an internet connection. If Xcode is installed (as /Applications/Xcode.app or /Applications/Xcode-beta.app), the result items contain a reference to the header file that defines the error in the respective SDK. 45 | LBResult 46 | A list of matching errors. 47 | LBScripts 48 | 49 | LBDefaultScript 50 | 51 | LBAcceptedArgumentTypes 52 | 53 | string 54 | 55 | LBKeepWindowActive 56 | 57 | LBRequiresArgument 58 | 59 | LBResultType 60 | unknown 61 | LBReturnsResult 62 | 63 | LBScriptName 64 | default.js 65 | 66 | 67 | LBTextInputTitle 68 | Error name or code, framework, or header 69 | NSHumanReadableCopyright 70 | Copyright © 2015 Marco Masser, osstatus.com by Seth Willits (@sethwillits) 71 | 72 | 73 | -------------------------------------------------------------------------------- /Source/Swift Demangle.lbaction/Contents/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Resources/Swift Logo.pdf 8 | 9 | BAGNHkYlhahdd5JhajCwWDO5qWw= 10 | 11 | 12 | files2 13 | 14 | Resources/Swift Logo.pdf 15 | 16 | hash 17 | 18 | BAGNHkYlhahdd5JhajCwWDO5qWw= 19 | 20 | hash2 21 | 22 | sz3yt93oViEx7DPsftzZTA4HgdCCnuFn0VJZh1elvV8= 23 | 24 | 25 | Scripts/default.sh 26 | 27 | hash 28 | 29 | PoCj6QcNNG0odUKJrLsyIjQ9DKc= 30 | 31 | hash2 32 | 33 | 7D/xQvcc7f0PZ/rAUX8vMrjqAfbNyubozkAvYc1dQts= 34 | 35 | 36 | 37 | rules 38 | 39 | ^Resources/ 40 | 41 | ^Resources/.*\.lproj/ 42 | 43 | optional 44 | 45 | weight 46 | 1000 47 | 48 | ^Resources/.*\.lproj/locversion.plist$ 49 | 50 | omit 51 | 52 | weight 53 | 1100 54 | 55 | ^version.plist$ 56 | 57 | 58 | rules2 59 | 60 | .*\.dSYM($|/) 61 | 62 | weight 63 | 11 64 | 65 | ^(.*/)?\.DS_Store$ 66 | 67 | omit 68 | 69 | weight 70 | 2000 71 | 72 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 73 | 74 | nested 75 | 76 | weight 77 | 10 78 | 79 | ^.* 80 | 81 | ^Info\.plist$ 82 | 83 | omit 84 | 85 | weight 86 | 20 87 | 88 | ^PkgInfo$ 89 | 90 | omit 91 | 92 | weight 93 | 20 94 | 95 | ^Resources/ 96 | 97 | weight 98 | 20 99 | 100 | ^Resources/.*\.lproj/ 101 | 102 | optional 103 | 104 | weight 105 | 1000 106 | 107 | ^Resources/.*\.lproj/locversion.plist$ 108 | 109 | omit 110 | 111 | weight 112 | 1100 113 | 114 | ^[^/]+$ 115 | 116 | nested 117 | 118 | weight 119 | 10 120 | 121 | ^embedded\.provisionprofile$ 122 | 123 | weight 124 | 20 125 | 126 | ^version\.plist$ 127 | 128 | weight 129 | 20 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /Source/Create New Swift Playground (OS X).lbaction/Contents/Scripts/default.swift: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env xcrun swift 2 | 3 | import Cocoa 4 | 5 | @noreturn func logAndExit(message: String) { 6 | NSLog(message) 7 | exit(1) 8 | } 9 | 10 | enum LaunchBar { 11 | 12 | static func actionBundle() -> NSBundle { 13 | #if true 14 | guard let actionBundleURL = NSProcessInfo.processInfo().fileURLForEnvironmentKey("LB_ACTION_PATH") else { 15 | logAndExit("Environment does not have a value for LB_ACTION_PATH") 16 | } 17 | #else 18 | let actionBundleURL = NSURL(fileURLWithPath: ("~/Library/Application Support/LaunchBar/Actions/Create New Swift Playground (OS X).lbaction" as NSString).stringByExpandingTildeInPath) 19 | #endif 20 | 21 | guard let bundle = NSBundle(URL: actionBundleURL) else { 22 | logAndExit("LB_ACTION_PATH does not point to a valid bundle") 23 | } 24 | return bundle 25 | } 26 | 27 | static func actionSupportDirectoryURL() -> NSURL { 28 | #if true 29 | guard let actionSupportDirectoryURL = NSProcessInfo.processInfo().fileURLForEnvironmentKey("LB_SUPPORT_PATH") else { 30 | logAndExit("Environment does not have a value for LB_SUPPORT_PATH") 31 | } 32 | #else 33 | let actionSupportDirectoryURL = NSURL(fileURLWithPath: ("~/Library/Application Support/LaunchBar/Action Support/com.duckcode.LaunchBar.action.CreateNewSwiftPlayground" as NSString).stringByExpandingTildeInPath) 34 | #endif 35 | 36 | return actionSupportDirectoryURL 37 | } 38 | 39 | static func isShiftKeyDown() -> Bool { 40 | return NSProcessInfo.processInfo().boolForEnvironmentKey("LB_OPTION_SHIFT_KEY") ?? false 41 | } 42 | 43 | } 44 | 45 | extension NSProcessInfo { 46 | 47 | func fileURLForEnvironmentKey(key: String) -> NSURL? { 48 | guard let environmentValue = environment[key] else { 49 | return nil 50 | } 51 | return NSURL.fileURLWithPath(environmentValue) 52 | } 53 | 54 | func boolForEnvironmentKey(key: String) -> Bool? { 55 | guard let environmentValue = environment[key] else { 56 | return nil 57 | } 58 | return Int(environmentValue) == 1 59 | } 60 | 61 | } 62 | 63 | enum Action { 64 | 65 | static func templateFileURL() -> NSURL { 66 | guard let templateFileURL = LaunchBar.actionBundle().URLForResource("Template", withExtension: "playground") else { 67 | logAndExit("Cannot find Template.playground file") 68 | } 69 | return templateFileURL 70 | } 71 | 72 | static func destinationDirectoryURL() -> NSURL { 73 | let preferences = Action.preferences() 74 | guard let destinationDirectoryPath = preferences["destinationDirectory"] as? String else { 75 | logAndExit("Error to determine destination directory") 76 | } 77 | return NSURL(fileURLWithPath: (destinationDirectoryPath as NSString).stringByExpandingTildeInPath) 78 | } 79 | 80 | static func defaultDestinationDirectoryPath() -> String { 81 | let documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) 82 | guard let documentDirectoryPath = documentDirectories.first else { 83 | logAndExit("Unable to find document directory") 84 | } 85 | return (documentDirectoryPath as NSString).stringByAbbreviatingWithTildeInPath 86 | } 87 | 88 | static func defaultPreferences() -> [String: AnyObject] { 89 | return ["destinationDirectory": defaultDestinationDirectoryPath()] 90 | } 91 | 92 | static func preferences() -> [String: AnyObject] { 93 | let preferencesFileURL = LaunchBar.actionSupportDirectoryURL().URLByAppendingPathComponent("preferences.plist", isDirectory: false) 94 | if let preferences = NSDictionary(contentsOfURL: preferencesFileURL) as? [String: AnyObject] { 95 | return preferences 96 | } 97 | 98 | let defaultPreferences = Action.defaultPreferences() 99 | (defaultPreferences as NSDictionary).writeToURL(preferencesFileURL, atomically: true) 100 | return defaultPreferences 101 | } 102 | 103 | static func playgroundName() -> String { 104 | var playgroundName: String! 105 | if Process.arguments.count == 1 { 106 | let formatter = NSDateFormatter() 107 | formatter.dateStyle = .ShortStyle 108 | formatter.timeStyle = .MediumStyle 109 | let dateString = formatter.stringFromDate(NSDate()) 110 | playgroundName = "New Playground (\(dateString))" 111 | } else { 112 | playgroundName = Process.arguments[1] 113 | } 114 | playgroundName = playgroundName.stringByReplacingOccurrencesOfString(":", withString: "-") 115 | playgroundName = playgroundName.stringByReplacingOccurrencesOfString("/", withString: "-") 116 | playgroundName = playgroundName + ".playground" 117 | return playgroundName 118 | } 119 | 120 | static func playgroundFileURL() -> NSURL { 121 | let destinationDirectoryURL = Action.destinationDirectoryURL() 122 | return destinationDirectoryURL.URLByAppendingPathComponent(playgroundName(), isDirectory: false) 123 | } 124 | 125 | } 126 | 127 | 128 | let playgroundFileURL = Action.playgroundFileURL() 129 | var isRegularFile: AnyObject? 130 | _ = try? playgroundFileURL.getResourceValue(&isRegularFile, forKey: NSURLIsRegularFileKey) 131 | if (isRegularFile as? NSNumber)?.boolValue != true { 132 | do { 133 | try NSFileManager.defaultManager().copyItemAtURL(Action.templateFileURL(), toURL: playgroundFileURL) 134 | } catch { 135 | logAndExit("Error: \(error)") 136 | } 137 | } 138 | 139 | if LaunchBar.isShiftKeyDown() { 140 | print(playgroundFileURL.path!) 141 | } else { 142 | NSWorkspace.sharedWorkspace().openFile(playgroundFileURL.path!) 143 | } 144 | -------------------------------------------------------------------------------- /Source/Create New Swift Playground (iOS).lbaction/Contents/Scripts/default.swift: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env xcrun swift 2 | 3 | import Cocoa 4 | 5 | @noreturn func logAndExit(message: String) { 6 | NSLog(message) 7 | exit(1) 8 | } 9 | 10 | enum LaunchBar { 11 | 12 | static func actionBundle() -> NSBundle { 13 | #if true 14 | guard let actionBundleURL = NSProcessInfo.processInfo().fileURLForEnvironmentKey("LB_ACTION_PATH") else { 15 | logAndExit("Environment does not have a value for LB_ACTION_PATH") 16 | } 17 | #else 18 | let actionBundleURL = NSURL(fileURLWithPath: ("~/Library/Application Support/LaunchBar/Actions/Create New Swift Playground (OS X).lbaction" as NSString).stringByExpandingTildeInPath) 19 | #endif 20 | 21 | guard let bundle = NSBundle(URL: actionBundleURL) else { 22 | logAndExit("LB_ACTION_PATH does not point to a valid bundle") 23 | } 24 | return bundle 25 | } 26 | 27 | static func actionSupportDirectoryURL() -> NSURL { 28 | #if true 29 | guard let actionSupportDirectoryURL = NSProcessInfo.processInfo().fileURLForEnvironmentKey("LB_SUPPORT_PATH") else { 30 | logAndExit("Environment does not have a value for LB_SUPPORT_PATH") 31 | } 32 | #else 33 | let actionSupportDirectoryURL = NSURL(fileURLWithPath: ("~/Library/Application Support/LaunchBar/Action Support/com.duckcode.LaunchBar.action.CreateNewSwiftPlayground" as NSString).stringByExpandingTildeInPath) 34 | #endif 35 | 36 | return actionSupportDirectoryURL 37 | } 38 | 39 | static func isShiftKeyDown() -> Bool { 40 | return NSProcessInfo.processInfo().boolForEnvironmentKey("LB_OPTION_SHIFT_KEY") ?? false 41 | } 42 | 43 | } 44 | 45 | extension NSProcessInfo { 46 | 47 | func fileURLForEnvironmentKey(key: String) -> NSURL? { 48 | guard let environmentValue = environment[key] else { 49 | return nil 50 | } 51 | return NSURL.fileURLWithPath(environmentValue) 52 | } 53 | 54 | func boolForEnvironmentKey(key: String) -> Bool? { 55 | guard let environmentValue = environment[key] else { 56 | return nil 57 | } 58 | return Int(environmentValue) == 1 59 | } 60 | 61 | } 62 | 63 | enum Action { 64 | 65 | static func templateFileURL() -> NSURL { 66 | guard let templateFileURL = LaunchBar.actionBundle().URLForResource("Template", withExtension: "playground") else { 67 | logAndExit("Cannot find Template.playground file") 68 | } 69 | return templateFileURL 70 | } 71 | 72 | static func destinationDirectoryURL() -> NSURL { 73 | let preferences = Action.preferences() 74 | guard let destinationDirectoryPath = preferences["destinationDirectory"] as? String else { 75 | logAndExit("Error to determine destination directory") 76 | } 77 | return NSURL(fileURLWithPath: (destinationDirectoryPath as NSString).stringByExpandingTildeInPath) 78 | } 79 | 80 | static func defaultDestinationDirectoryPath() -> String { 81 | let documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) 82 | guard let documentDirectoryPath = documentDirectories.first else { 83 | logAndExit("Unable to find document directory") 84 | } 85 | return (documentDirectoryPath as NSString).stringByAbbreviatingWithTildeInPath 86 | } 87 | 88 | static func defaultPreferences() -> [String: AnyObject] { 89 | return ["destinationDirectory": defaultDestinationDirectoryPath()] 90 | } 91 | 92 | static func preferences() -> [String: AnyObject] { 93 | let preferencesFileURL = LaunchBar.actionSupportDirectoryURL().URLByAppendingPathComponent("preferences.plist", isDirectory: false) 94 | if let preferences = NSDictionary(contentsOfURL: preferencesFileURL) as? [String: AnyObject] { 95 | return preferences 96 | } 97 | 98 | let defaultPreferences = Action.defaultPreferences() 99 | (defaultPreferences as NSDictionary).writeToURL(preferencesFileURL, atomically: true) 100 | return defaultPreferences 101 | } 102 | 103 | static func playgroundName() -> String { 104 | var playgroundName: String! 105 | if Process.arguments.count == 1 { 106 | let formatter = NSDateFormatter() 107 | formatter.dateStyle = .ShortStyle 108 | formatter.timeStyle = .MediumStyle 109 | let dateString = formatter.stringFromDate(NSDate()) 110 | playgroundName = "New Playground (\(dateString))" 111 | } else { 112 | playgroundName = Process.arguments[1] 113 | } 114 | playgroundName = playgroundName.stringByReplacingOccurrencesOfString(":", withString: "-") 115 | playgroundName = playgroundName.stringByReplacingOccurrencesOfString("/", withString: "-") 116 | playgroundName = playgroundName + ".playground" 117 | return playgroundName 118 | } 119 | 120 | static func playgroundFileURL() -> NSURL { 121 | let destinationDirectoryURL = Action.destinationDirectoryURL() 122 | return destinationDirectoryURL.URLByAppendingPathComponent(playgroundName(), isDirectory: false) 123 | } 124 | 125 | } 126 | 127 | 128 | let playgroundFileURL = Action.playgroundFileURL() 129 | var isRegularFile: AnyObject? 130 | _ = try? playgroundFileURL.getResourceValue(&isRegularFile, forKey: NSURLIsRegularFileKey) 131 | if (isRegularFile as? NSNumber)?.boolValue != true { 132 | do { 133 | try NSFileManager.defaultManager().copyItemAtURL(Action.templateFileURL(), toURL: playgroundFileURL) 134 | } catch { 135 | logAndExit("Error: \(error)") 136 | } 137 | } 138 | 139 | if LaunchBar.isShiftKeyDown() { 140 | print(playgroundFileURL.path!) 141 | } else { 142 | NSWorkspace.sharedWorkspace().openFile(playgroundFileURL.path!) 143 | } 144 | -------------------------------------------------------------------------------- /Source/Search OSStatus.lbaction/Contents/Scripts/default.js: -------------------------------------------------------------------------------- 1 | // LaunchBar Action Script 2 | 3 | var ERROR_ICON = '/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertStopIcon.icns'; 4 | var ERROR_DESCRIPTION_ICON = '/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertNoteIcon.icns'; 5 | var QUESTION_MARK_ICON = '/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericQuestionMarkIcon.icns'; 6 | 7 | var NOT_FOUND_MARKER = 'NOT_FOUND_MARKER'; 8 | 9 | function run() { 10 | LaunchBar.openURL('http://www.osstatus.com'); 11 | } 12 | 13 | function runWithString(input) { 14 | if (input == undefined || input.length == 0) { 15 | return; 16 | } 17 | var searchURL = 'http://www.osstatus.com/api/search/errors.json?search=' + encodeURIComponent(input); 18 | var result = HTTP.getJSON(searchURL); 19 | 20 | if (result.data == undefined) { 21 | return; 22 | } 23 | 24 | var items = []; 25 | for (var i in result.data) { 26 | var item = resultItemFromData(result.data[i]); 27 | if (item != undefined) { 28 | items.push(item); 29 | } 30 | } 31 | 32 | switch (items.length) { 33 | case 0: 34 | return { 35 | title: 'No error codes found', 36 | icon: QUESTION_MARK_ICON, 37 | }; 38 | 39 | case 1: 40 | return items[0].children; 41 | 42 | default: 43 | return items; 44 | } 45 | } 46 | 47 | function resultItemFromData(data) { 48 | verifyData(data); 49 | var valueInfoItem = createValueInfoItem(data); 50 | return { 51 | title: data.name, 52 | subtitle: data.description, 53 | alwaysShowsSubtitle: true, 54 | badge: valueInfoItem.title, 55 | icon: ERROR_ICON, 56 | children: [ 57 | { 58 | title: data.name, 59 | badge: 'Name', 60 | icon: '', 61 | }, 62 | { 63 | title: data.description, 64 | badge: 'Description', 65 | icon: ERROR_DESCRIPTION_ICON, 66 | }, 67 | valueInfoItem, 68 | createPlatformItem(data), 69 | createFrameworkItem(data.framework), 70 | createHeaderItem(data.header_file, data.framework), 71 | ], 72 | } 73 | } 74 | 75 | function verifyData(data) { 76 | if (data.description == null) { 77 | data.description = 'No description'; 78 | } 79 | 80 | // When searching for 'Foundation', the first result is ' NSContainerSpecifierError' 81 | // with an unnecessary space at the beginning, so we have to call trim() on the name: 82 | data.name = data.name.trim(); 83 | 84 | // When searching for 'MKErrorDirectionsNotFound', the header is missing its .h extension: 85 | if (data.header_file.lastIndexOf('.') == -1) { 86 | data.header_file += '.h' 87 | } 88 | } 89 | 90 | function createPlatformItem(data) { 91 | var mapping = { 92 | 'platform_mac': 'OS X', 93 | 'platform_ios': 'iOS', 94 | 'platform_watch': 'watchOS', 95 | 'platform_tv': 'tvOS', 96 | }; 97 | 98 | var resultComponents = []; 99 | for (key in mapping) { 100 | var candidate = data[key]; 101 | if (candidate != undefined && candidate != null) { 102 | resultComponents.push(mapping[key]); 103 | } 104 | } 105 | 106 | if (resultComponents.length == 0) { 107 | return { 108 | title: 'None', 109 | badge: 'Platforms', 110 | icon: QUESTION_MARK_ICON, 111 | }; 112 | } else { 113 | var icon = resultComponents[0]; 114 | if (data.platform_mac && data.platform_ios) { 115 | icon = 'OS X & iOS'; 116 | } 117 | 118 | return { 119 | title: resultComponents.join(', '), 120 | badge: 'Platforms', 121 | icon: icon, 122 | }; 123 | } 124 | } 125 | 126 | function createValueInfoItem(data) { 127 | var mapping = { 128 | 'value_integer': 'Integer', 129 | 'value_ostype': 'OSType', 130 | 'value_string': 'String', 131 | 'value_hex': 'Hex', 132 | }; 133 | 134 | for (key in mapping) { 135 | var candidate = data[key]; 136 | if (candidate != undefined && candidate != null) { 137 | return { 138 | title: candidate, 139 | badge: mapping[key] + ' value', 140 | icon: ERROR_ICON, 141 | }; 142 | } 143 | } 144 | 145 | return { 146 | title: 'Unknown', 147 | type: 'Unknown', 148 | icon: QUESTION_MARK_ICON, 149 | }; 150 | } 151 | 152 | function createFrameworkItem(frameworkName) { 153 | var frameworkPath = frameworkPathForFrameworkWithName(frameworkName); 154 | if (frameworkPath != undefined) { 155 | return { path: frameworkPath }; 156 | } 157 | 158 | return { 159 | title: frameworkName, 160 | badge: 'Framework', 161 | icon: QUESTION_MARK_ICON 162 | }; 163 | } 164 | 165 | // Keys are the name of the framework. Values are: 166 | // - full path (string) if already found. 167 | // - NOT_FOUND_MARKER if already searched, but not found. 168 | var frameworkPathCache = {}; 169 | function frameworkPathForFrameworkWithName(frameworkName) { 170 | var frameworkPath = frameworkPathCache[frameworkName]; 171 | if (frameworkPath != undefined) { 172 | if (frameworkPath == NOT_FOUND_MARKER) { 173 | // Already searched, but not found. 174 | return; 175 | } 176 | return frameworkPath; 177 | } 178 | 179 | var rootPaths = [ 180 | // Prefer Xcode-beta.app: 181 | '/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/', 182 | '/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/', 183 | '/Applications/Xcode-beta.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk/', 184 | '/Applications/Xcode-beta.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/', 185 | 186 | // Xcode.app: 187 | '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/', 188 | '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/', 189 | '/Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk/', 190 | '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/', 191 | 192 | // Fallback to system's framework folder, which does not have any headers: 193 | '/', 194 | ]; 195 | 196 | // The OS X SDK has the version number in it, so we'll find it and add it as the first 197 | // SDK path to search. The other SDKs have a version number in their name too, but there's 198 | // a link without a version number that points to the current one. 199 | var macSDK = macSDKPath(); 200 | if (macSDK != undefined) { 201 | rootPaths.splice(0, 0, macSDK + '/'); 202 | } 203 | 204 | // All kinds of paths that may have frameworks in them on any platform: 205 | var frameworkPaths = [ 206 | 'System/Library/Frameworks/', 207 | 'System/Library/Frameworks/Accelerate.framework/Frameworks/', 208 | 'System/Library/Frameworks/ApplicationServices.framework/Frameworks/', 209 | 'System/Library/Frameworks/Automator.framework/Frameworks/', 210 | 'System/Library/Frameworks/Carbon.framework/Frameworks/', 211 | 'System/Library/Frameworks/CoreServices.framework/Frameworks/', 212 | 'System/Library/Frameworks/IMServicePlugIn.framework/Frameworks/', 213 | 'System/Library/Frameworks/IOBluetooth.framework/Frameworks/', 214 | 'System/Library/Frameworks/JavaVM.framework/Frameworks/', 215 | 'System/Library/Frameworks/OpenDirectory.framework/Frameworks/', 216 | 'System/Library/Frameworks/Quartz.framework/Frameworks/', 217 | 'System/Library/Frameworks/WebKit.framework/Frameworks/', 218 | 'System/Library/LocationBundles/', 219 | 'System/Library/PrivateFrameworks/', 220 | ]; 221 | 222 | for (i in rootPaths) { 223 | for (var j in frameworkPaths) { 224 | var candidate = rootPaths[i] + frameworkPaths[j] + frameworkName + '.framework'; 225 | if (File.exists(candidate)) { 226 | frameworkPathCache[frameworkName] = candidate; 227 | return candidate; 228 | } 229 | } 230 | } 231 | 232 | frameworkPathCache[frameworkName] = NOT_FOUND_MARKER; 233 | } 234 | 235 | // The path to the latest OS X SDK in /Applications/Xcode.app: 236 | // - undefined if not yet checked. 237 | // - NOT_FOUND_MARKER if not found. 238 | // - full path (string) otherwise. 239 | var macSDKPathCache = undefined; 240 | function macSDKPath() { 241 | if (macSDKPathCache == undefined) { 242 | var macSDKsPath = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/'; 243 | var macSDKName = File.getDirectoryContents(macSDKsPath).pop(); 244 | if (macSDKName == undefined) { 245 | macSDKPathCache = NOT_FOUND_MARKER; 246 | return; 247 | } 248 | 249 | macSDKPathCache = macSDKsPath + macSDKName; 250 | } 251 | return macSDKPathCache == NOT_FOUND_MARKER ? undefined : macSDKPathCache; 252 | } 253 | 254 | function createHeaderItem(headerName, frameworkName) { 255 | var headerPath = headerPathForHeaderWithName(headerName, frameworkName); 256 | if (headerPath != undefined) { 257 | return { path: headerPath }; 258 | } 259 | 260 | return { 261 | title: headerName, 262 | badge: 'Header File', 263 | icon: QUESTION_MARK_ICON 264 | }; 265 | } 266 | 267 | // Keys are the name of the header file. Values are: 268 | // - full path (string) if already found. 269 | // - NOT_FOUND_MARKER if already searched, but not found. 270 | var headerPathCache = {}; 271 | function headerPathForHeaderWithName(headerName, frameworkName) { 272 | var cacheKey = frameworkName + '/' + headerName; 273 | var headerPath = headerPathCache[cacheKey]; 274 | if (headerPath != undefined) { 275 | if (headerPath == NOT_FOUND_MARKER) { 276 | // Already searched, but not found. 277 | return; 278 | } 279 | return headerPath; 280 | } 281 | 282 | var frameworkPath = frameworkPathForFrameworkWithName(frameworkName); 283 | if (frameworkPath == undefined) { 284 | headerPathCache[cacheKey] = NOT_FOUND_MARKER; 285 | return; 286 | } 287 | 288 | var frameworkHeadersPath = frameworkPath + '/Headers/'; 289 | 290 | // Best case: header file is directly in ".framework/Headers" directory: 291 | var headerPath = frameworkHeadersPath + headerName; 292 | if (File.exists(headerPath)) { 293 | headerPathCache[cacheKey] = headerPath; 294 | return headerPath; 295 | } 296 | 297 | // Search ".framework/Headers" subdirectories: 298 | headerPath = recursivelyFindFileInDirectory(headerName, frameworkHeadersPath); 299 | if (headerPath != undefined) { 300 | headerPathCache[cacheKey] = headerPath; 301 | return headerPath; 302 | } 303 | 304 | headerPathCache[cacheKey] = NOT_FOUND_MARKER; 305 | } 306 | 307 | function recursivelyFindFileInDirectory(filename, directoryPath) { 308 | 309 | // Sanity check: 310 | if (!File.isDirectory(directoryPath)) { 311 | return; 312 | } 313 | 314 | // Check if file exists: 315 | var filePath = directoryPath + '/' + filename; 316 | if (File.exists(filePath)) { 317 | return filePath; 318 | } 319 | 320 | var subdirectories; 321 | try { 322 | subdirectories = File.getDirectoryContents(directoryPath); 323 | } catch (exception) { 324 | // LaunchBar 6.5 (6122) didn't resolve symbolic links and getDirectoryContents() would throw an exception. 325 | return; 326 | } 327 | 328 | // Search all subdirectories: 329 | for (i in subdirectories) { 330 | var subdirectory = directoryPath + '/' + subdirectories[i]; 331 | if (File.isDirectory(subdirectory)) { 332 | var filePath = recursivelyFindFileInDirectory(filename, subdirectory); 333 | if (filePath != undefined) { 334 | return filePath; 335 | } 336 | } 337 | } 338 | } 339 | --------------------------------------------------------------------------------