Skip to content

Commit

Permalink
user script channel termination error
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmassicotte committed Feb 7, 2024
1 parent 94bb1bb commit f1610f7
Showing 1 changed file with 23 additions and 10 deletions.
33 changes: 23 additions & 10 deletions Sources/LanguageClient/DataChannel+UserScript.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ private let userScriptDirectory = try? FileManager.default.url(

extension DataChannel {

@available(macOS 12.0, *)
@available(*, deprecated, message: "Please use the version that returns an error in the termination handler")
public static func userScriptChannel(
scriptPath: String,
arguments: [String] = [],
terminationHandler: @escaping @Sendable () -> Void
) throws -> DataChannel {
try userScriptChannel(scriptPath: scriptPath, terminationHandler: { _ in terminationHandler() })
}

/// Create a `DataChannel` that connects to an application user script in the application scripts directory.
///
/// Based around `NSUserUnixTask`. See more here: https://developer.apple.com/documentation/foundation/nsuserunixtask.
Expand All @@ -28,7 +38,7 @@ extension DataChannel {
public static func userScriptChannel(
scriptPath: String,
arguments: [String] = [],
terminationHandler: @escaping @Sendable () -> Void
terminationHandler: @escaping @Sendable (Error?) -> Void
) throws -> DataChannel {
guard let scriptURL = userScriptDirectory?.appendingPathComponent(scriptPath) else {
throw CocoaError(.fileNoSuchFile)
Expand Down Expand Up @@ -61,19 +71,22 @@ extension DataChannel {

// Launch the script asynchronously
Task {
do {
defer { continuation.finish() }

// NB: Needs to happen in the task as `NSUserUnixTask` is not sendable.
let unixTask = try NSUserUnixTask(url: scriptURL)

// NB: Needs to happen in the task as `NSUserUnixTask` is not sendable.
let unixTask = try NSUserUnixTask(url: scriptURL)
unixTask.standardInput = stdinPipe.fileHandleForReading
unixTask.standardOutput = stdoutPipe.fileHandleForWriting
unixTask.standardError = stderrPipe.fileHandleForWriting

unixTask.standardInput = stdinPipe.fileHandleForReading
unixTask.standardOutput = stdoutPipe.fileHandleForWriting
unixTask.standardError = stderrPipe.fileHandleForWriting
try await unixTask.execute(withArguments: arguments)

defer {
continuation.finish()
terminationHandler()
terminationHandler(nil)
} catch {
terminationHandler(error)
}
try await unixTask.execute(withArguments: arguments)
}

// Forward messages from the data channel into stdin
Expand Down

0 comments on commit f1610f7

Please sign in to comment.