1+ import BuiltinExtension
12import Foundation
23import Preferences
34import SuggestionModel
45import SuggestionProvider
56import UserDefaultsObserver
67import Workspace
78
9+ #if canImport(ProExtension)
10+ import ProExtension
11+ #endif
12+
813public 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
0 commit comments