11import Foundation
2+ import LanguageServerProtocol
23
34extension FileManager {
45 func fileIsDirectory( atPath path: String ) -> Bool {
@@ -9,19 +10,86 @@ extension FileManager {
910}
1011
1112@discardableResult
12- func runAppleScript( _ appleScript: String ) async throws -> String ? {
13+ func runAppleScript( _ appleScript: String ) async throws -> String {
1314 let task = Process ( )
1415 task. launchPath = " /usr/bin/osascript "
1516 task. arguments = [ " -e " , appleScript]
1617 let outpipe = Pipe ( )
1718 task. standardOutput = outpipe
18- try task. run ( )
19- await Task . yield ( )
20- task. waitUntilExit ( )
21- if let data = try outpipe. fileHandleForReading. readToEnd ( ) ,
22- let content = String ( data: data, encoding: . utf8)
23- {
24- return content
19+
20+ return try await withUnsafeThrowingContinuation { continuation in
21+ do {
22+ task. terminationHandler = { _ in
23+ do {
24+ if let data = try outpipe. fileHandleForReading. readToEnd ( ) ,
25+ let content = String ( data: data, encoding: . utf8)
26+ {
27+ continuation. resume ( returning: content)
28+ return
29+ }
30+ continuation. resume ( returning: " " )
31+ } catch {
32+ continuation. resume ( throwing: error)
33+ }
34+ }
35+ try task. run ( )
36+ } catch {
37+ continuation. resume ( throwing: error)
38+ }
39+ }
40+ }
41+
42+ extension XPCService {
43+ @ServiceActor
44+ func fetchOrCreateWorkspaceIfNeeded( fileURL: URL ) async throws -> Workspace {
45+ let projectURL = try await Environment . fetchCurrentProjectRootURL ( fileURL)
46+ let workspaceURL = projectURL ?? fileURL
47+ let workspace = workspaces [ workspaceURL] ?? Workspace ( projectRootURL: workspaceURL)
48+ workspaces [ workspaceURL] = workspace
49+ return workspace
50+ }
51+ }
52+
53+ extension NSError {
54+ static func from( _ error: Error ) -> NSError {
55+ if let error = error as? ServerError {
56+ var message = " Unknown "
57+ switch error {
58+ case let . handlerUnavailable( handler) :
59+ message = " Handler unavailable: \( handler) . "
60+ case let . unhandledMethod( method) :
61+ message = " Methond unhandled: \( method) . "
62+ case let . notificationDispatchFailed( error) :
63+ message = " Notification dispatch failed: \( error. localizedDescription) . "
64+ case let . requestDispatchFailed( error) :
65+ message = " Request dispatch failed: \( error. localizedDescription) . "
66+ case let . clientDataUnavailable( error) :
67+ message = " Client data unavalable: \( error. localizedDescription) . "
68+ case . serverUnavailable:
69+ message = " Server unavailable, please make sure you have installed Node. "
70+ case . missingExpectedParameter:
71+ message = " Missing expected parameter. "
72+ case . missingExpectedResult:
73+ message = " Missing expected result. "
74+ case let . unableToDecodeRequest( error) :
75+ message = " Unable to decode request: \( error. localizedDescription) . "
76+ case let . unableToSendRequest( error) :
77+ message = " Unable to send request: \( error. localizedDescription) . "
78+ case let . unableToSendNotification( error) :
79+ message = " Unable to send notification: \( error. localizedDescription) . "
80+ case let . serverError( code, m, _) :
81+ message = " Server error: ( \( code) ) \( m) . "
82+ case let . invalidRequest( error) :
83+ message = " Invalid request: \( error? . localizedDescription ?? " Unknown " ) . "
84+ case . timeout:
85+ message = " Timeout. "
86+ }
87+ return NSError ( domain: " com.intii.CopilotForXcode " , code: - 1 , userInfo: [
88+ NSLocalizedDescriptionKey: message,
89+ ] )
90+ }
91+ return NSError ( domain: " com.intii.CopilotForXcode " , code: - 1 , userInfo: [
92+ NSLocalizedDescriptionKey: error. localizedDescription,
93+ ] )
2594 }
26- return nil
2795}
0 commit comments