Skip to content

Commit 360f3b8

Browse files
committed
Adjust Workspace
1 parent 3a25e7a commit 360f3b8

File tree

9 files changed

+100
-70
lines changed

9 files changed

+100
-70
lines changed

Core/Sources/Service/GUI/WidgetDataSource.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ final class WidgetDataSource {
8787

8888
extension WidgetDataSource: SuggestionWidgetDataSource {
8989
func suggestionForFile(at url: URL) async -> SuggestionProvider? {
90-
for workspace in await Service.shared.workspacePool.workspaces.values {
91-
if let filespace = await workspace.filespaces[url],
92-
let suggestion = await filespace.presentingSuggestion
90+
for workspace in Service.shared.workspacePool.workspaces.values {
91+
if let filespace = workspace.filespaces[url],
92+
let suggestion = filespace.presentingSuggestion
9393
{
94-
return await .init(
94+
return .init(
9595
code: suggestion.text,
9696
language: filespace.language,
9797
startLineIndex: suggestion.position.line,

Core/Sources/Service/RealtimeSuggestionController.swift

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,8 @@ import QuartzCore
1212
import Workspace
1313
import XcodeInspector
1414

15-
@WorkspaceActor
1615
public class RealtimeSuggestionController {
17-
var eventObserver: CGEventObserverType = CGEventObserver(eventsOfInterest: [
18-
.keyUp,
19-
.keyDown,
20-
.rightMouseDown,
21-
.leftMouseDown,
22-
])
16+
let eventObserver: CGEventObserverType = CGEventObserver(eventsOfInterest: [.keyDown])
2317
private var task: Task<Void, Error>?
2418
private var inflightPrefetchTask: Task<Void, Error>?
2519
private var windowChangeObservationTask: Task<Void, Error>?
@@ -28,11 +22,13 @@ public class RealtimeSuggestionController {
2822
private var focusedUIElement: AXUIElement?
2923
private var sourceEditor: SourceEditor?
3024

31-
init() {
25+
init() {}
26+
27+
func start() {
3228
Task { [weak self] in
3329
if let app = ActiveApplicationMonitor.activeXcode {
3430
self?.handleXcodeChanged(app)
35-
self?.startHIDObservation(by: 1)
31+
self?.startHIDObservation()
3632
}
3733
var previousApp = ActiveApplicationMonitor.activeXcode
3834
for await app in ActiveApplicationMonitor.createStream() {
@@ -45,17 +41,15 @@ public class RealtimeSuggestionController {
4541
}
4642

4743
if ActiveApplicationMonitor.activeXcode != nil {
48-
startHIDObservation(by: 1)
44+
startHIDObservation()
4945
} else {
50-
stopHIDObservation(by: 1)
46+
stopHIDObservation()
5147
}
5248
}
5349
}
5450
}
5551

56-
private func startHIDObservation(by listener: AnyHashable) {
57-
Logger.service.info("Add auto trigger listener: \(listener).")
58-
52+
private func startHIDObservation() {
5953
if task == nil {
6054
task = Task { [weak self, eventObserver] in
6155
for await event in eventObserver.createStream() {
@@ -67,8 +61,7 @@ public class RealtimeSuggestionController {
6761
eventObserver.activateIfPossible()
6862
}
6963

70-
private func stopHIDObservation(by listener: AnyHashable) {
71-
Logger.service.info("Remove auto trigger listener: \(listener).")
64+
private func stopHIDObservation() {
7265
task?.cancel()
7366
task = nil
7467
eventObserver.deactivate()
@@ -241,7 +234,7 @@ public class RealtimeSuggestionController {
241234
func notifyEditingFileChange(editor: AXUIElement) async {
242235
guard let fileURL = try? await Environment.fetchCurrentFileURL(),
243236
let (workspace, filespace) = try? await Service.shared.workspacePool
244-
.fetchOrCreateWorkspaceAndFilespace(fileURL: fileURL)
237+
.fetchOrCreateWorkspaceAndFilespace(fileURL: fileURL)
245238
else { return }
246239
workspace.suggestionPlugin?.notifyUpdateFile(filespace: filespace, content: editor.value)
247240
}

Core/Sources/Service/ScheduledCleaner.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ public final class ScheduledCleaner {
1616
) {
1717
self.workspacePool = workspacePool
1818
self.guiController = guiController
19+
}
1920

21+
func start() {
2022
// occasionally cleanup workspaces.
2123
Task { @ServiceActor in
2224
while !Task.isCancelled {
@@ -53,21 +55,21 @@ public final class ScheduledCleaner {
5355
}
5456
}
5557
}
56-
for (url, workspace) in await workspacePool.workspaces {
57-
if await workspace.isExpired, workspaceInfos[.url(url)] == nil {
58+
for (url, workspace) in workspacePool.workspaces {
59+
if workspace.isExpired, workspaceInfos[.url(url)] == nil {
5860
Logger.service.info("Remove idle workspace")
59-
for url in await workspace.filespaces.keys {
61+
for url in workspace.filespaces.keys {
6062
await guiController.widgetDataSource.cleanup(for: url)
6163
}
6264
await workspace.cleanUp(availableTabs: [])
63-
await workspacePool.removeWorkspace(url: url)
65+
workspacePool.removeWorkspace(url: url)
6466
} else {
6567
let tabs = (workspaceInfos[.url(url)]?.tabs ?? [])
6668
.union(workspaceInfos[.unknown]?.tabs ?? [])
6769
// cleanup chats for unused files
68-
let filespaces = await workspace.filespaces
70+
let filespaces = workspace.filespaces
6971
for (url, _) in filespaces {
70-
if await workspace.isFilespaceExpired(
72+
if workspace.isFilespaceExpired(
7173
fileURL: url,
7274
availableTabs: tabs
7375
) {
@@ -83,7 +85,7 @@ public final class ScheduledCleaner {
8385

8486
@ServiceActor
8587
public func closeAllChildProcesses() async {
86-
for (_, workspace) in await workspacePool.workspaces {
88+
for (_, workspace) in workspacePool.workspaces {
8789
await workspace.terminateSuggestionService()
8890
}
8991
}

Core/Sources/Service/WorkspaceExtension/Filespace+SuggestionService.swift

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,17 @@ import Foundation
22
import SuggestionModel
33
import Workspace
44

5-
struct FilespaceCodeMetadata: Equatable {
6-
var uti: String?
7-
var tabSize: Int?
8-
var indentSize: Int?
9-
var usesTabsForIndentation: Bool?
10-
}
11-
125
struct FilespaceSuggestionSnapshot: Equatable {
136
var linesHash: Int
147
var cursorPosition: CursorPosition
158
}
169

17-
struct FilespaceCodeMetadataKey: FilespacePropertyKey {
18-
static func createDefaultValue() -> FilespaceCodeMetadata { .init() }
19-
}
20-
2110
struct FilespaceSuggestionSnapshotKey: FilespacePropertyKey {
2211
static func createDefaultValue()
2312
-> FilespaceSuggestionSnapshot { .init(linesHash: -1, cursorPosition: .outOfScope) }
2413
}
2514

2615
extension FilespacePropertyValues {
27-
var codeMetadata: FilespaceCodeMetadata {
28-
get { self[FilespaceCodeMetadataKey.self] }
29-
set { self[FilespaceCodeMetadataKey.self] = newValue }
30-
}
31-
3216
var suggestionSourceSnapshot: FilespaceSuggestionSnapshot {
3317
get { self[FilespaceSuggestionSnapshotKey.self] }
3418
set { self[FilespaceSuggestionSnapshotKey.self] = newValue }
@@ -47,6 +31,7 @@ extension Filespace {
4731
/// - lines: lines of the file
4832
/// - cursorPosition: cursor position
4933
/// - Returns: `true` if the suggestion is still valid
34+
@WorkspaceActor
5035
func validateSuggestions(lines: [String], cursorPosition: CursorPosition) -> Bool {
5136
guard let presentingSuggestion else { return false }
5237

Core/Sources/Service/WorkspaceExtension/Workspace+Cleanup.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Workspace
33
import SuggestionService
44

55
extension Workspace {
6+
@WorkspaceActor
67
func cleanUp(availableTabs: Set<String>) {
78
for (fileURL, _) in filespaces {
89
if isFilespaceExpired(fileURL: fileURL, availableTabs: availableTabs) {

Core/Sources/Service/WorkspaceExtension/Workspace+SuggestionService.swift

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ extension Workspace {
2525
}
2626

2727
extension Workspace {
28+
@WorkspaceActor
2829
@discardableResult
2930
func generateSuggestions(
3031
forFileAt fileURL: URL,
@@ -58,35 +59,31 @@ extension Workspace {
5859
usesTabsForIndentation: editor.usesTabsForIndentation,
5960
ignoreSpaceOnlySuggestions: true
6061
)
61-
62-
filespace.suggestions = completions
63-
filespace.suggestionIndex = 0
62+
63+
filespace.setSuggestions(completions)
6464

6565
return completions
6666
}
6767

68+
@WorkspaceActor
6869
func selectNextSuggestion(forFileAt fileURL: URL) {
6970
refreshUpdateTime()
7071
guard let filespace = filespaces[fileURL],
7172
filespace.suggestions.count > 1
7273
else { return }
73-
filespace.suggestionIndex += 1
74-
if filespace.suggestionIndex >= filespace.suggestions.endIndex {
75-
filespace.suggestionIndex = 0
76-
}
74+
filespace.nextSuggestion()
7775
}
7876

77+
@WorkspaceActor
7978
func selectPreviousSuggestion(forFileAt fileURL: URL) {
8079
refreshUpdateTime()
8180
guard let filespace = filespaces[fileURL],
8281
filespace.suggestions.count > 1
8382
else { return }
84-
filespace.suggestionIndex -= 1
85-
if filespace.suggestionIndex < 0 {
86-
filespace.suggestionIndex = filespace.suggestions.endIndex - 1
87-
}
83+
filespace.previousSuggestion()
8884
}
8985

86+
@WorkspaceActor
9087
func rejectSuggestion(forFileAt fileURL: URL, editor: EditorContent?) {
9188
refreshUpdateTime()
9289

@@ -102,6 +99,7 @@ extension Workspace {
10299
filespaces[fileURL]?.reset()
103100
}
104101

102+
@WorkspaceActor
105103
func acceptSuggestion(forFileAt fileURL: URL, editor: EditorContent?) -> CodeSuggestion? {
106104
refreshUpdateTime()
107105
guard let filespace = filespaces[fileURL],

Tool/Sources/Workspace/Filespace.swift

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ public protocol FilespacePropertyKey {
77
static func createDefaultValue() -> Value
88
}
99

10-
@WorkspaceActor
1110
public final class FilespacePropertyValues {
1211
var storage: [ObjectIdentifier: Any] = [:]
1312

@@ -26,16 +25,35 @@ public final class FilespacePropertyValues {
2625
}
2726
}
2827

29-
@WorkspaceActor
28+
public struct FilespaceCodeMetadata: Equatable {
29+
public var uti: String?
30+
public var tabSize: Int?
31+
public var indentSize: Int?
32+
public var usesTabsForIndentation: Bool?
33+
34+
init(
35+
uti: String? = nil,
36+
tabSize: Int? = nil,
37+
indentSize: Int? = nil,
38+
usesTabsForIndentation: Bool? = nil
39+
) {
40+
self.uti = uti
41+
self.tabSize = tabSize
42+
self.indentSize = indentSize
43+
self.usesTabsForIndentation = usesTabsForIndentation
44+
}
45+
}
46+
3047
@dynamicMemberLookup
3148
public final class Filespace {
3249
public let fileURL: URL
3350
public private(set) lazy var language: String = languageIdentifierFromFileURL(fileURL).rawValue
34-
public var suggestions: [CodeSuggestion] = [] {
51+
public var codeMetadata: FilespaceCodeMetadata = .init()
52+
public private(set) var suggestions: [CodeSuggestion] = [] {
3553
didSet { refreshUpdateTime() }
3654
}
3755

38-
public var suggestionIndex: Int = 0
56+
public private(set) var suggestionIndex: Int = 0
3957

4058
public var presentingSuggestion: CodeSuggestion? {
4159
guard suggestions.endIndex > suggestionIndex, suggestionIndex >= 0 else { return nil }
@@ -45,7 +63,7 @@ public final class Filespace {
4563
public var isExpired: Bool {
4664
Environment.now().timeIntervalSince(lastSuggestionUpdateTime) > 60 * 3
4765
}
48-
66+
4967
private(set) var lastSuggestionUpdateTime: Date = Environment.now()
5068
var additionalProperties = FilespacePropertyValues()
5169
let fileSaveWatcher: FileSaveWatcher
@@ -68,14 +86,15 @@ public final class Filespace {
6886
onSave(self)
6987
}
7088
}
71-
89+
7290
public subscript<K>(
7391
dynamicMember dynamicMember: WritableKeyPath<FilespacePropertyValues, K>
7492
) -> K {
7593
get { additionalProperties[keyPath: dynamicMember] }
7694
set { additionalProperties[keyPath: dynamicMember] = newValue }
7795
}
7896

97+
@WorkspaceActor
7998
public func reset() {
8099
suggestions = []
81100
suggestionIndex = 0
@@ -84,5 +103,27 @@ public final class Filespace {
84103
public func refreshUpdateTime() {
85104
lastSuggestionUpdateTime = Environment.now()
86105
}
106+
107+
@WorkspaceActor
108+
public func setSuggestions(_ suggestions: [CodeSuggestion]) {
109+
self.suggestions = suggestions
110+
suggestionIndex = 0
111+
}
112+
113+
@WorkspaceActor
114+
public func nextSuggestion() {
115+
suggestionIndex += 1
116+
if suggestionIndex >= suggestions.endIndex {
117+
suggestionIndex = 0
118+
}
119+
}
120+
121+
@WorkspaceActor
122+
public func previousSuggestion() {
123+
suggestionIndex -= 1
124+
if suggestionIndex < 0 {
125+
suggestionIndex = suggestions.endIndex - 1
126+
}
127+
}
87128
}
88129

0 commit comments

Comments
 (0)