Skip to content

Commit f90f64a

Browse files
committed
Add node path customization
1 parent 8b8ec91 commit f90f64a

File tree

5 files changed

+132
-76
lines changed

5 files changed

+132
-76
lines changed

Copilot for Xcode/LaunchAgentView.swift

Lines changed: 66 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,86 @@
11
import SwiftUI
2+
import XPCShared
23

34
struct LaunchAgentView: View {
45
@State var errorMessage: String?
56
@State var isDidRemoveLaunchAgentAlertPresented = false
67
@State var isDidSetupLaunchAgentAlertPresented = false
78
@State var isDidRestartLaunchAgentAlertPresented = false
8-
9+
@AppStorage(SettingsKey.nodePath, store: .shared) var nodePath: String = ""
10+
911
var body: some View {
1012
Section {
11-
HStack {
12-
Button(action: {
13-
do {
14-
try LaunchAgentManager().setupLaunchAgent()
15-
isDidSetupLaunchAgentAlertPresented = true
16-
} catch {
17-
errorMessage = error.localizedDescription
13+
VStack(alignment: .leading, spacing: 8) {
14+
HStack {
15+
Button(action: {
16+
do {
17+
try LaunchAgentManager().setupLaunchAgent()
18+
isDidSetupLaunchAgentAlertPresented = true
19+
} catch {
20+
errorMessage = error.localizedDescription
21+
}
22+
}) {
23+
Text("Set Up Launch Agent for XPC Service")
1824
}
19-
}) {
20-
Text("Set Up Launch Agent for XPC Service")
21-
}
22-
.alert(isPresented: $isDidSetupLaunchAgentAlertPresented) {
23-
.init(
24-
title: Text("Finished Launch Agent Setup"),
25-
message: Text(
26-
"You may need to restart Xcode to make the extension work."
27-
),
28-
dismissButton: .default(Text("OK"))
29-
)
30-
}
31-
32-
Button(action: {
33-
do {
34-
try LaunchAgentManager().removeLaunchAgent()
35-
isDidRemoveLaunchAgentAlertPresented = true
36-
} catch {
37-
errorMessage = error.localizedDescription
25+
.alert(isPresented: $isDidSetupLaunchAgentAlertPresented) {
26+
.init(
27+
title: Text("Finished Launch Agent Setup"),
28+
message: Text(
29+
"You may need to restart Xcode to make the extension work."
30+
),
31+
dismissButton: .default(Text("OK"))
32+
)
3833
}
39-
}) {
40-
Text("Remove Launch Agent")
41-
}
42-
.alert(isPresented: $isDidRemoveLaunchAgentAlertPresented) {
43-
.init(
44-
title: Text("Launch Agent Removed"),
45-
dismissButton: .default(Text("OK"))
46-
)
47-
}
48-
49-
Button(action: {
50-
LaunchAgentManager().restartLaunchAgent()
51-
isDidRestartLaunchAgentAlertPresented = true
52-
}) {
53-
Text("Restart XPC Service")
54-
}.alert(isPresented: $isDidRestartLaunchAgentAlertPresented) {
55-
.init(
56-
title: Text("Launch Agent Restarted"),
57-
dismissButton: .default(Text("OK"))
58-
)
59-
}
6034

61-
EmptyView()
62-
.alert(isPresented: .init(
63-
get: { errorMessage != nil },
64-
set: { yes in
65-
if !yes { errorMessage = nil }
35+
Button(action: {
36+
do {
37+
try LaunchAgentManager().removeLaunchAgent()
38+
isDidRemoveLaunchAgentAlertPresented = true
39+
} catch {
40+
errorMessage = error.localizedDescription
6641
}
67-
)) {
42+
}) {
43+
Text("Remove Launch Agent")
44+
}
45+
.alert(isPresented: $isDidRemoveLaunchAgentAlertPresented) {
46+
.init(
47+
title: Text("Launch Agent Removed"),
48+
dismissButton: .default(Text("OK"))
49+
)
50+
}
51+
52+
Button(action: {
53+
LaunchAgentManager().restartLaunchAgent()
54+
isDidRestartLaunchAgentAlertPresented = true
55+
}) {
56+
Text("Restart XPC Service")
57+
}.alert(isPresented: $isDidRestartLaunchAgentAlertPresented) {
6858
.init(
69-
title: Text("Failed. Got to the GitHub page for Help"),
70-
message: Text(errorMessage ?? "Unknown Error"),
59+
title: Text("Launch Agent Restarted"),
7160
dismissButton: .default(Text("OK"))
7261
)
7362
}
63+
64+
EmptyView()
65+
.alert(isPresented: .init(
66+
get: { errorMessage != nil },
67+
set: { yes in
68+
if !yes { errorMessage = nil }
69+
}
70+
)) {
71+
.init(
72+
title: Text("Failed. Got to the GitHub page for Help"),
73+
message: Text(errorMessage ?? "Unknown Error"),
74+
dismissButton: .default(Text("OK"))
75+
)
76+
}
77+
}
78+
79+
HStack {
80+
Text("Path to Node: ")
81+
TextField("node", text: $nodePath)
82+
.textFieldStyle(.copilot)
83+
}
7484
}
7585
}.buttonStyle(.copilot)
7686
}

Copilot for Xcode/Styles.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ struct CopilotButtonStyle: ButtonStyle {
55
configuration.label
66
.padding(.vertical, 4)
77
.padding(.horizontal, 8)
8+
.foregroundColor(.white)
89
.background(
910
RoundedRectangle(cornerRadius: 4, style: .continuous)
1011
.fill(
@@ -24,3 +25,40 @@ struct CopilotButtonStyle: ButtonStyle {
2425
extension ButtonStyle where Self == CopilotButtonStyle {
2526
static var copilot: CopilotButtonStyle { CopilotButtonStyle() }
2627
}
28+
29+
struct CopilotTextFieldStyle: TextFieldStyle {
30+
func _body(configuration: TextField<_Label>) -> some View {
31+
configuration
32+
.colorScheme(.dark)
33+
.textFieldStyle(.plain)
34+
.foregroundColor(.white)
35+
.padding(.vertical, 4)
36+
.padding(.horizontal, 8)
37+
.background(
38+
RoundedRectangle(cornerRadius: 4, style: .continuous)
39+
.fill(.white.opacity(0.2))
40+
)
41+
.overlay {
42+
RoundedRectangle(cornerRadius: 4, style: .continuous)
43+
.stroke(.white.opacity(0.2), style: .init(lineWidth: 1))
44+
}
45+
}
46+
}
47+
48+
extension TextFieldStyle where Self == CopilotTextFieldStyle {
49+
static var copilot: CopilotTextFieldStyle { CopilotTextFieldStyle() }
50+
}
51+
52+
struct CopilotStyle_Previews: PreviewProvider {
53+
static var previews: some View {
54+
VStack(alignment: .leading, spacing: 8) {
55+
Button("Button") {}
56+
.buttonStyle(.copilot)
57+
58+
TextField("title", text: .constant("Placeholder"))
59+
.textFieldStyle(.copilot)
60+
}
61+
.padding(.all, 8)
62+
.background(Color.black)
63+
}
64+
}

Core/Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ let package = Package(
1313
),
1414
.library(
1515
name: "Client",
16-
targets: ["CopilotModel", "Client"]
16+
targets: ["CopilotModel", "Client", "XPCShared"]
1717
),
1818
],
1919
dependencies: [
@@ -22,7 +22,7 @@ let package = Package(
2222
targets: [
2323
.target(
2424
name: "CopilotService",
25-
dependencies: ["LanguageClient", "CopilotModel"]
25+
dependencies: ["LanguageClient", "CopilotModel", "XPCShared"]
2626
),
2727
.testTarget(
2828
name: "CopilotServiceTests",

Core/Sources/CopilotService/CopilotService.swift

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import CopilotModel
22
import Foundation
33
import LanguageClient
44
import LanguageServerProtocol
5+
import XPCShared
56

67
public protocol CopilotAuthServiceType {
78
func checkStatus() async throws -> CopilotStatus
@@ -40,22 +41,25 @@ public class CopilotBaseService {
4041
try? FileManager.default
4142
.createDirectory(at: supportURL, withIntermediateDirectories: false)
4243
}
43-
let executionParams = Process.ExecutionParameters(
44-
path: "/usr/bin/env",
45-
arguments: [
46-
"node",
47-
Bundle.main.url(
48-
forResource: "agent",
49-
withExtension: "js",
50-
subdirectory: "copilot/dist"
51-
)!.path,
52-
"--stdio",
53-
],
54-
environment: [
55-
"PATH": "/usr/bin:/usr/local/bin",
56-
],
57-
currentDirectoryURL: supportURL
58-
)
44+
let executionParams = {
45+
let nodePath = UserDefaults.shared.string(forKey: SettingsKey.nodePath) ?? ""
46+
return Process.ExecutionParameters(
47+
path: "/usr/bin/env",
48+
arguments: [
49+
nodePath.isEmpty ? "node" : nodePath,
50+
Bundle.main.url(
51+
forResource: "agent",
52+
withExtension: "js",
53+
subdirectory: "copilot/dist"
54+
)!.path,
55+
"--stdio",
56+
],
57+
environment: [
58+
"PATH": "/usr/bin:/usr/local/bin",
59+
],
60+
currentDirectoryURL: supportURL
61+
)
62+
}()
5963
let localServer = LocalProcessServer(executionParameters: executionParams)
6064
localServer.logMessages = false
6165
let server = InitializingServer(server: localServer)
@@ -85,11 +89,11 @@ public class CopilotBaseService {
8589
workspaceFolders: nil
8690
)
8791
}
88-
92+
8993
server.notificationHandler = { _, respond in
9094
respond(nil)
9195
}
92-
96+
9397
return server
9498
}()
9599
}

Core/Sources/XPCShared/UserDefaults.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ import Foundation
33
public extension UserDefaults {
44
static var shared = UserDefaults(suiteName: "5YKZ4Y3DAW.group.com.intii.CopilotForXcode")!
55
}
6+
7+
public enum SettingsKey {
8+
public static let nodePath = "NodePath"
9+
}

0 commit comments

Comments
 (0)