Skip to content

Commit 8261fac

Browse files
committed
Adjust definition of SuggestionServiceProvider
1 parent 3c8a745 commit 8261fac

File tree

3 files changed

+65
-87
lines changed

3 files changed

+65
-87
lines changed

Tool/Sources/SuggestionProvider/SuggestionProvider.swift

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import AppKit
22
import struct CopilotForXcodeKit.SuggestionServiceConfiguration
3+
import struct CopilotForXcodeKit.WorkspaceInfo
34
import Foundation
45
import Preferences
56
import SuggestionModel
@@ -55,15 +56,19 @@ public struct RelevantCodeSnippet: Codable {
5556
}
5657

5758
public protocol SuggestionServiceProvider {
58-
func getSuggestions(_ request: SuggestionRequest) async throws -> [CodeSuggestion]
59-
func notifyAccepted(_ suggestion: CodeSuggestion) async
60-
func notifyRejected(_ suggestions: [CodeSuggestion]) async
61-
func notifyOpenTextDocument(fileURL: URL, content: String) async throws
62-
func notifyChangeTextDocument(fileURL: URL, content: String) async throws
63-
func notifyCloseTextDocument(fileURL: URL) async throws
64-
func notifySaveTextDocument(fileURL: URL) async throws
65-
func cancelRequest() async
66-
func terminate() async
59+
func getSuggestions(
60+
_ request: SuggestionRequest,
61+
workspaceInfo: CopilotForXcodeKit.WorkspaceInfo
62+
) async throws -> [CodeSuggestion]
63+
func notifyAccepted(
64+
_ suggestion: CodeSuggestion,
65+
workspaceInfo: CopilotForXcodeKit.WorkspaceInfo
66+
) async
67+
func notifyRejected(
68+
_ suggestions: [CodeSuggestion],
69+
workspaceInfo: CopilotForXcodeKit.WorkspaceInfo
70+
) async
71+
func cancelRequest(workspaceInfo: CopilotForXcodeKit.WorkspaceInfo) async
6772

6873
var configuration: SuggestionServiceConfiguration { get async }
6974
}
Lines changed: 32 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,36 @@
1+
import BuiltinExtension
12
import Foundation
23
import Preferences
34
import SuggestionModel
45
import SuggestionProvider
56
import UserDefaultsObserver
67
import Workspace
78

9+
#if canImport(ProExtension)
10+
import ProExtension
11+
#endif
12+
813
public final class SuggestionServiceWorkspacePlugin: WorkspacePlugin {
9-
public typealias SuggestionServiceFactory = (
10-
_ projectRootURL: URL,
11-
_ onServiceLaunched: @escaping (any SuggestionServiceProvider) -> Void
12-
) -> any SuggestionServiceProvider
13-
14-
let userDefaultsObserver = UserDefaultsObserver(
14+
public typealias SuggestionServiceFactory = () -> any SuggestionServiceProvider
15+
let suggestionServiceFactory: SuggestionServiceFactory
16+
17+
let suggestionFeatureUsabilityObserver = UserDefaultsObserver(
1518
object: UserDefaults.shared, forKeyPaths: [
1619
UserDefaultPreferenceKeys().suggestionFeatureEnabledProjectList.key,
1720
UserDefaultPreferenceKeys().disableSuggestionFeatureGlobally.key,
1821
], context: nil
1922
)
2023

24+
let providerChangeObserver = UserDefaultsObserver(
25+
object: UserDefaults.shared,
26+
forKeyPaths: [UserDefaultPreferenceKeys().suggestionFeatureProvider.key],
27+
context: nil
28+
)
29+
2130
public var isRealtimeSuggestionEnabled: Bool {
2231
UserDefaults.shared.value(for: \.realtimeSuggestionToggle)
2332
}
2433

25-
let suggestionServiceFactory: SuggestionServiceFactory
26-
2734
private var _suggestionService: SuggestionServiceProvider?
2835

2936
public var suggestionService: SuggestionServiceProvider? {
@@ -40,13 +47,7 @@ public final class SuggestionServiceWorkspacePlugin: WorkspacePlugin {
4047
}
4148

4249
if _suggestionService == nil {
43-
_suggestionService = suggestionServiceFactory(projectRootURL) {
44-
[weak self] _ in
45-
guard let self else { return }
46-
for (_, filespace) in filespaces {
47-
notifyOpenFile(filespace: filespace)
48-
}
49-
}
50+
_suggestionService = suggestionServiceFactory()
5051
}
5152
return _suggestionService
5253
}
@@ -62,77 +63,37 @@ public final class SuggestionServiceWorkspacePlugin: WorkspacePlugin {
6263
}
6364
return true
6465
}
65-
66+
6667
public init(
6768
workspace: Workspace,
6869
suggestionProviderFactory: @escaping SuggestionServiceFactory
6970
) {
70-
self.suggestionServiceFactory = suggestionProviderFactory
71+
suggestionServiceFactory = suggestionProviderFactory
7172
super.init(workspace: workspace)
7273

73-
userDefaultsObserver.onChange = { [weak self] in
74+
suggestionFeatureUsabilityObserver.onChange = { [weak self] in
7475
guard let self else { return }
7576
_ = self.suggestionService
7677
}
77-
}
7878

79-
override public func didOpenFilespace(_ filespace: Filespace) {
80-
notifyOpenFile(filespace: filespace)
81-
}
82-
83-
override public func didSaveFilespace(_ filespace: Filespace) {
84-
notifySaveFile(filespace: filespace)
85-
}
86-
87-
override public func didUpdateFilespace(_ filespace: Filespace, content: String) {
88-
notifyUpdateFile(filespace: filespace, content: content)
89-
}
90-
91-
override public func didCloseFilespace(_ fileURL: URL) {
92-
Task {
93-
try await suggestionService?.notifyCloseTextDocument(fileURL: fileURL)
94-
}
95-
}
96-
97-
public func notifyOpenFile(filespace: Filespace) {
98-
Task {
99-
guard filespace.isTextReadable else { return }
100-
guard !(await filespace.isGitIgnored) else { return }
101-
// check if file size is larger than 15MB, if so, return immediately
102-
if let attrs = try? FileManager.default
103-
.attributesOfItem(atPath: filespace.fileURL.path),
104-
let fileSize = attrs[FileAttributeKey.size] as? UInt64,
105-
fileSize > 15 * 1024 * 1024
106-
{ return }
107-
108-
try await suggestionService?.notifyOpenTextDocument(
109-
fileURL: filespace.fileURL,
110-
content: String(contentsOf: filespace.fileURL, encoding: .utf8)
111-
)
112-
}
113-
}
114-
115-
public func notifyUpdateFile(filespace: Filespace, content: String) {
116-
Task {
117-
guard filespace.isTextReadable else { return }
118-
guard !(await filespace.isGitIgnored) else { return }
119-
try await suggestionService?.notifyChangeTextDocument(
120-
fileURL: filespace.fileURL,
121-
content: content
122-
)
79+
providerChangeObserver.onChange = { [weak self] in
80+
guard let self else { return }
81+
self._suggestionService = nil
12382
}
12483
}
12584

126-
public func notifySaveFile(filespace: Filespace) {
127-
Task {
128-
guard filespace.isTextReadable else { return }
129-
guard !(await filespace.isGitIgnored) else { return }
130-
try await suggestionService?.notifySaveTextDocument(fileURL: filespace.fileURL)
131-
}
85+
func notifyAccepted(_ suggestion: CodeSuggestion) async {
86+
await suggestionService?.notifyAccepted(
87+
suggestion,
88+
workspaceInfo: .init(workspaceURL: workspaceURL, projectURL: projectRootURL)
89+
)
13290
}
13391

134-
public func terminateSuggestionService() async {
135-
await _suggestionService?.terminate()
92+
func notifyRejected(_ suggestions: [CodeSuggestion]) async {
93+
await suggestionService?.notifyRejected(
94+
suggestions,
95+
workspaceInfo: .init(workspaceURL: workspaceURL, projectURL: projectRootURL)
96+
)
13697
}
13798
}
13899

Tool/Sources/WorkspaceSuggestionService/Workspace+SuggestionService.swift

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,14 @@ public extension Workspace {
6060
relativePath: fileURL.path.replacingOccurrences(of: projectRootURL.path, with: ""),
6161
content: editor.lines.joined(separator: ""),
6262
lines: editor.lines,
63-
cursorPosition: editor.cursorPosition,
63+
cursorPosition: editor.cursorPosition,
6464
cursorOffset: editor.cursorOffset,
6565
tabSize: editor.tabSize,
6666
indentSize: editor.indentSize,
6767
usesTabsForIndentation: editor.usesTabsForIndentation,
6868
relevantCodeSnippets: []
69-
)
69+
),
70+
workspaceInfo: .init(workspaceURL: projectRootURL, projectURL: projectRootURL)
7071
)
7172

7273
filespace.setSuggestions(completions)
@@ -102,9 +103,15 @@ public extension Workspace {
102103
filespaces[fileURL]?.codeMetadata.indentSize = editor.indentSize
103104
filespaces[fileURL]?.codeMetadata.usesTabsForIndentation = editor.usesTabsForIndentation
104105
}
105-
106+
106107
Task {
107-
await suggestionService?.notifyRejected(filespaces[fileURL]?.suggestions ?? [])
108+
await suggestionService?.notifyRejected(
109+
filespaces[fileURL]?.suggestions ?? [],
110+
workspaceInfo: .init(
111+
workspaceURL: projectRootURL,
112+
projectURL: projectRootURL
113+
)
114+
)
108115
}
109116
filespaces[fileURL]?.reset()
110117
}
@@ -128,9 +135,14 @@ public extension Workspace {
128135
var allSuggestions = filespace.suggestions
129136
let suggestion = allSuggestions.remove(at: filespace.suggestionIndex)
130137

131-
Task { [allSuggestions] in
132-
await suggestionService?.notifyAccepted(suggestion)
133-
await suggestionService?.notifyRejected(allSuggestions)
138+
Task {
139+
await suggestionService?.notifyAccepted(
140+
suggestion,
141+
workspaceInfo: .init(
142+
workspaceURL: projectRootURL,
143+
projectURL: projectRootURL
144+
)
145+
)
134146
}
135147

136148
filespaces[fileURL]?.reset()

0 commit comments

Comments
 (0)