         version: "1.0.1",
     description: "the OSX app terminator"
 )
+/**
+ attempt to execute throwable block
+
+ - seealso: [Implementing printing versions of “try?” and “try!” — on steroids! in #swiftlang](http://ericasadun.com/2015/11/05/implementing-printing-versions-of-try-and-try-on-steroids-in-swiftlang/)
+*/
+func attempt<T>(block: () throws -> T) -> Optional<T> {
+    do { return try block() }
+    catch { print(error); return nil }
+}
+enum SniperError: ErrorType {
+    case InvalidArgument, TargetNotFound
+}
 class Target: CommandType {
     let commandName = "target"
     let commandShortDescription = "List all running apps's info."

        print("Terminating \(app.bundleIdentifier ?? UnknownBundleID): \(app.processIdentifier) ...")
        app.terminate()
    }
    enum SniperError: ErrorType {
        case InvalidArgument, TargetNotFound
    }
    func execute(arguments: CommandArguments) throws  {
        if let _ = pid, _ = bundleId {
            print("Cannot specify both bundleID(-b) and PID(-p) at the same time.")


    func execute(arguments: CommandArguments) throws  {
        let keyword = arguments.optionalArgument("keyword")
        let apps = try getApps(keyword)
        print("\(apps.count) app\(apps.count == 1 ? "" : "s") found.")
        for app in apps {
            print("\(app.bundleIdentifier ?? UnknownBundleID): \(app.processIdentifier)")
        }
    }
    func getApps(keyword:String? = nil) throws -> [NSRunningApplication] {
        let apps = NSWorkspace.sharedWorkspace().runningApplications
        switch keyword {
        case .None:
            return apps
        case .Some(let keyword):
            guard let regex = attempt({
                try NSRegularExpression(pattern: "\(keyword)", options: .CaseInsensitive)
            }) else {
                throw SniperError.InvalidArgument
            }
            return apps.filter{
                guard let bundle = $0.bundleIdentifier else {
                    return false
