File tree Expand file tree Collapse file tree 2 files changed +56
-2
lines changed
Core/Sources/SuggestionWidget Expand file tree Collapse file tree 2 files changed +56
-2
lines changed Original file line number Diff line number Diff line change 1+ import Combine
2+ import Foundation
3+ import Perception
4+ import SuggestionModel
5+ import XcodeInspector
6+
7+ @Perceptible
8+ final class CursorPositionTracker {
9+ @MainActor
10+ var cursorPosition : CursorPosition = . zero
11+
12+ @PerceptionIgnored var editorObservationTask : Set < AnyCancellable > = [ ]
13+ @PerceptionIgnored var eventObservationTask : Task < Void , Never > ?
14+
15+ init ( ) {
16+ observeAppChange ( )
17+ }
18+
19+ deinit {
20+ eventObservationTask? . cancel ( )
21+ }
22+
23+ private func observeAppChange( ) {
24+ editorObservationTask = [ ]
25+ Task {
26+ await XcodeInspector . shared. safe. $focusedEditor. sink { [ weak self] editor in
27+ guard let editor, let self else { return }
28+ Task { @MainActor in
29+ self . observeAXNotifications ( editor)
30+ }
31+ } . store ( in: & editorObservationTask)
32+ }
33+ }
34+
35+ private func observeAXNotifications( _ editor: SourceEditor ) {
36+ eventObservationTask? . cancel ( )
37+ let content = editor. getLatestEvaluatedContent ( )
38+ Task { @MainActor in
39+ self . cursorPosition = content. cursorPosition
40+ }
41+ eventObservationTask = Task { [ weak self] in
42+ for await event in await editor. axNotifications. notifications ( ) {
43+ guard let self else { return }
44+ guard event. kind == . evaluatedContentChanged else { continue }
45+ let content = editor. getLatestEvaluatedContent ( )
46+ Task { @MainActor in
47+ self . cursorPosition = content. cursorPosition
48+ }
49+ }
50+ }
51+ }
52+ }
53+
Original file line number Diff line number Diff line change @@ -599,6 +599,7 @@ public final class WidgetWindows {
599599 let store : StoreOf < WidgetFeature >
600600 let chatTabPool : ChatTabPool
601601 weak var controller : WidgetWindowsController ?
602+ let cursorPositionTracker = CursorPositionTracker ( )
602603
603604 // you should make these window `.transient` so they never show up in the mission control.
604605
@@ -670,7 +671,7 @@ public final class WidgetWindows {
670671 state: \. sharedPanelState,
671672 action: \. sharedPanel
672673 )
673- )
674+ ) . environment ( cursorPositionTracker )
674675 )
675676 it. setIsVisible ( true )
676677 it. canBecomeKeyChecker = { [ store] in
@@ -704,7 +705,7 @@ public final class WidgetWindows {
704705 state: \. suggestionPanelState,
705706 action: \. suggestionPanel
706707 )
707- )
708+ ) . environment ( cursorPositionTracker )
708709 )
709710 it. canBecomeKeyChecker = { false }
710711 it. setIsVisible ( true )
You can’t perform that action at this time.
0 commit comments