forked from intitni/CopilotForXcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSuggestionWorkspacePlugin.swift
More file actions
128 lines (110 loc) · 4.38 KB
/
SuggestionWorkspacePlugin.swift
File metadata and controls
128 lines (110 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import Environment
import Foundation
import UserDefaultsObserver
import Workspace
import SuggestionService
import SuggestionModel
import Preferences
public final class SuggestionServiceWorkspacePlugin: WorkspacePlugin {
let userDefaultsObserver = UserDefaultsObserver(
object: UserDefaults.shared, forKeyPaths: [
UserDefaultPreferenceKeys().suggestionFeatureEnabledProjectList.key,
UserDefaultPreferenceKeys().disableSuggestionFeatureGlobally.key,
], context: nil
)
public var isRealtimeSuggestionEnabled: Bool {
UserDefaults.shared.value(for: \.realtimeSuggestionToggle)
}
private var _suggestionService: SuggestionServiceType?
public var suggestionService: SuggestionServiceType? {
// Check if the workspace is disabled.
let isSuggestionDisabledGlobally = UserDefaults.shared
.value(for: \.disableSuggestionFeatureGlobally)
if isSuggestionDisabledGlobally {
let enabledList = UserDefaults.shared.value(for: \.suggestionFeatureEnabledProjectList)
if !enabledList.contains(where: { path in projectRootURL.path.hasPrefix(path) }) {
// If it's disable, remove the service
_suggestionService = nil
return nil
}
}
if _suggestionService == nil {
_suggestionService = SuggestionService(projectRootURL: projectRootURL) {
[weak self] _ in
guard let self else { return }
for (_, filespace) in filespaces {
notifyOpenFile(filespace: filespace)
}
}
}
return _suggestionService
}
public var isSuggestionFeatureEnabled: Bool {
let isSuggestionDisabledGlobally = UserDefaults.shared
.value(for: \.disableSuggestionFeatureGlobally)
if isSuggestionDisabledGlobally {
let enabledList = UserDefaults.shared.value(for: \.suggestionFeatureEnabledProjectList)
if !enabledList.contains(where: { path in projectRootURL.path.hasPrefix(path) }) {
return false
}
}
return true
}
public override init(workspace: Workspace) {
super.init(workspace: workspace)
userDefaultsObserver.onChange = { [weak self] in
guard let self else { return }
_ = self.suggestionService
}
}
public override func didOpenFilespace(_ filespace: Filespace) {
notifyOpenFile(filespace: filespace)
}
public override func didSaveFilespace(_ filespace: Filespace) {
notifySaveFile(filespace: filespace)
}
public override func didUpdateFilespace(_ filespace: Filespace, content: String) {
notifyUpdateFile(filespace: filespace, content: content)
}
public override func didCloseFilespace(_ fileURL: URL) {
Task {
try await suggestionService?.notifyCloseTextDocument(fileURL: fileURL)
}
}
public func notifyOpenFile(filespace: Filespace) {
workspace?.refreshUpdateTime()
workspace?.openedFileRecoverableStorage.openFile(fileURL: filespace.fileURL)
Task {
// check if file size is larger than 15MB, if so, return immediately
if let attrs = try? FileManager.default
.attributesOfItem(atPath: filespace.fileURL.path),
let fileSize = attrs[FileAttributeKey.size] as? UInt64,
fileSize > 15 * 1024 * 1024
{ return }
try await suggestionService?.notifyOpenTextDocument(
fileURL: filespace.fileURL,
content: try String(contentsOf: filespace.fileURL, encoding: .utf8)
)
}
}
public func notifyUpdateFile(filespace: Filespace, content: String) {
filespace.refreshUpdateTime()
workspace?.refreshUpdateTime()
Task {
try await suggestionService?.notifyChangeTextDocument(
fileURL: filespace.fileURL,
content: content
)
}
}
public func notifySaveFile(filespace: Filespace) {
filespace.refreshUpdateTime()
workspace?.refreshUpdateTime()
Task {
try await suggestionService?.notifySaveTextDocument(fileURL: filespace.fileURL)
}
}
public func terminateSuggestionService() async {
await _suggestionService?.terminate()
}
}