Skip to content

Commit 52ec0a7

Browse files
committed
Update suggestion panel to display content according to editing file url
1 parent 3f33162 commit 52ec0a7

File tree

3 files changed

+52
-27
lines changed

3 files changed

+52
-27
lines changed

Core/Sources/AXNotificationStream/AXNotificationStream.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public final class AXNotificationStream: AsyncSequence {
66
public typealias Stream = AsyncStream<Element>
77
public typealias Continuation = Stream.Continuation
88
public typealias AsyncIterator = Stream.AsyncIterator
9-
public typealias Element = (String, CFDictionary)
9+
public typealias Element = (name: String, info: CFDictionary)
1010

1111
private var continuation: Continuation
1212
private let stream: Stream

Core/Sources/Service/GUI/SuggestionPanelController.swift

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,26 @@ final class SuggestionPanelController {
3030

3131
private var windowChangeObservationTask: Task<Void, Error>?
3232
private var activeApplicationMonitorTask: Task<Void, Error>?
33-
private var activeApplication: NSRunningApplication? {
34-
ActiveApplicationMonitor.activeApplication
33+
private var xcode: NSRunningApplication?
34+
private var suggestionForFiles: [URL: Suggestion] = [:]
35+
36+
enum Suggestion {
37+
case code([String], startLineIndex: Int)
3538
}
3639

3740
nonisolated init() {
3841
Task { @MainActor in
3942
activeApplicationMonitorTask = Task { [weak self] in
40-
guard let self else { return }
4143
var previousApp: NSRunningApplication?
4244
for await app in ActiveApplicationMonitor.createStream() {
45+
guard let self else { return }
4346
try Task.checkCancellation()
4447
defer { previousApp = app }
45-
if let app, app.bundleIdentifier == "com.apple.dt.Xcode" {
48+
if let app = ActiveApplicationMonitor.activeXcode {
4649
if app != previousApp {
4750
windowChangeObservationTask?.cancel()
4851
windowChangeObservationTask = nil
49-
self.observeXcodeWindowChangeIfNeeded()
52+
self.observeXcodeWindowChangeIfNeeded(app)
5053
}
5154
}
5255

@@ -55,18 +58,44 @@ final class SuggestionPanelController {
5558
}
5659
}
5760
}
61+
62+
func suggestCode(_ code: String, startLineIndex: Int, fileURL: URL) {
63+
viewModel.suggestion = code.split(separator: "\n").map(String.init)
64+
viewModel.startLineIndex = startLineIndex
65+
suggestionForFiles[fileURL] = .code(viewModel.suggestion, startLineIndex: startLineIndex)
66+
}
5867

59-
private func observeXcodeWindowChangeIfNeeded() {
68+
private func observeXcodeWindowChangeIfNeeded(_ app: NSRunningApplication) {
69+
xcode = app
6070
guard windowChangeObservationTask == nil else { return }
6171
windowChangeObservationTask = Task { [weak self] in
62-
guard let self else { return }
6372
let notifications = AXNotificationStream(
64-
app: activeApplication!,
65-
notificationNames: kAXMovedNotification
73+
app: app,
74+
notificationNames:
75+
kAXMovedNotification,
76+
kAXResizedNotification,
77+
kAXMainWindowChangedNotification,
78+
kAXFocusedWindowChangedNotification,
79+
kAXFocusedUIElementChangedNotification
6680
)
67-
for await _ in notifications {
81+
for await notification in notifications {
82+
guard let self else { return }
6883
try Task.checkCancellation()
6984
self.updateWindowLocation()
85+
86+
if notification.name == kAXFocusedUIElementChangedNotification {
87+
guard let fileURL = try? await Environment.fetchCurrentFileURL(),
88+
let suggestion = suggestionForFiles[fileURL]
89+
else {
90+
viewModel.suggestion = []
91+
continue
92+
}
93+
switch suggestion {
94+
case let .code(code, startLineIndex):
95+
viewModel.suggestion = code
96+
viewModel.startLineIndex = startLineIndex
97+
}
98+
}
7099
}
71100
}
72101
}
@@ -76,10 +105,8 @@ final class SuggestionPanelController {
76105
/// - note: It's possible to get the scroll view's postion by getting position on the focus
77106
/// element.
78107
private func updateWindowLocation() {
79-
if let activeXcode = activeApplication,
80-
activeXcode.bundleIdentifier == "com.apple.dt.Xcode"
81-
{
82-
let application = AXUIElementCreateApplication(activeXcode.processIdentifier)
108+
if let xcode {
109+
let application = AXUIElementCreateApplication(xcode.processIdentifier)
83110
if let focusElement: AXUIElement = try? application
84111
.copyValue(key: kAXFocusedUIElementAttribute),
85112
let focusElementType: String = try? focusElement
@@ -126,11 +153,6 @@ final class SuggestionPanelViewModel: ObservableObject {
126153
}
127154

128155
@Published var isPanelDisplayed = true
129-
130-
func suggestCode(_ code: String, startLineIndex: Int) {
131-
suggestion = code.split(separator: "\n").map(String.init)
132-
self.startLineIndex = startLineIndex
133-
}
134156
}
135157

136158
struct SuggestionPanelView: View {

Core/Sources/Service/SuggestionCommandHandler/WindowBaseCommandHandler.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ struct WindowBaseCommandHandler: SuggestionCommandHanlder {
4040
)
4141

4242
if let suggestion = filespace.presentingSuggestion {
43-
presentSuggestion(suggestion, lines: editor.lines)
43+
presentSuggestion(suggestion, lines: editor.lines, fileURL: fileURL)
4444
} else {
4545
Task { @MainActor in
4646
GraphicalUserInterfaceController.shared.suggestionPanelController.viewModel
@@ -67,7 +67,7 @@ struct WindowBaseCommandHandler: SuggestionCommandHanlder {
6767
)
6868

6969
if let suggestion = filespace.presentingSuggestion {
70-
presentSuggestion(suggestion, lines: editor.lines)
70+
presentSuggestion(suggestion, lines: editor.lines, fileURL: fileURL)
7171
} else {
7272
Task { @MainActor in
7373
GraphicalUserInterfaceController.shared.suggestionPanelController.viewModel
@@ -94,7 +94,7 @@ struct WindowBaseCommandHandler: SuggestionCommandHanlder {
9494
)
9595

9696
if let suggestion = filespace.presentingSuggestion {
97-
presentSuggestion(suggestion, lines: editor.lines)
97+
presentSuggestion(suggestion, lines: editor.lines, fileURL: fileURL)
9898
} else {
9999
Task { @MainActor in
100100
GraphicalUserInterfaceController.shared.suggestionPanelController.viewModel
@@ -140,11 +140,14 @@ struct WindowBaseCommandHandler: SuggestionCommandHanlder {
140140
try await presentSuggestions(editor: editor)
141141
}
142142

143-
func presentSuggestion(_ suggestion: CopilotCompletion, lines: [String]) {
143+
func presentSuggestion(_ suggestion: CopilotCompletion, lines: [String], fileURL: URL) {
144144
Task { @MainActor in
145-
let viewModel = GraphicalUserInterfaceController.shared.suggestionPanelController
146-
.viewModel
147-
viewModel.suggestCode(suggestion.text, startLineIndex: suggestion.position.line)
145+
let controller = GraphicalUserInterfaceController.shared.suggestionPanelController
146+
controller.suggestCode(
147+
suggestion.text,
148+
startLineIndex: suggestion.position.line,
149+
fileURL: fileURL
150+
)
148151
}
149152
}
150153
}

0 commit comments

Comments
 (0)