1+ import ActiveApplicationMonitor
12import AppKit
23import CopilotService
34import Foundation
@@ -17,31 +18,8 @@ struct FailedToFetchFileURLError: Error, LocalizedError {
1718enum Environment {
1819 static var now = { Date ( ) }
1920
20- static var runningXcodes : ( ) async -> [ NSRunningApplication ] = {
21- var xcodes = [ NSRunningApplication] ( )
22- var retryCount = 0
23- // Sometimes runningApplications returns 0 items.
24- while xcodes. isEmpty, retryCount < 3 {
25- xcodes = NSRunningApplication
26- . runningApplications ( withBundleIdentifier: " com.apple.dt.Xcode " )
27- try ? await Task . sleep ( nanoseconds: 1_000_000 )
28- retryCount += 1
29- }
30- return xcodes
31- }
32-
3321 static var isXcodeActive : ( ) async -> Bool = {
34- var activeXcodes = [ NSRunningApplication] ( )
35- var retryCount = 0
36- // Sometimes runningApplications returns 0 items.
37- while activeXcodes. isEmpty, retryCount < 3 {
38- activeXcodes = NSRunningApplication
39- . runningApplications ( withBundleIdentifier: " com.apple.dt.Xcode " )
40- . filter ( \. isActive)
41- try ? await Task . sleep ( nanoseconds: 1_000_000 )
42- retryCount += 1
43- }
44- return !activeXcodes. isEmpty
22+ ActiveApplicationMonitor . activeXcode != nil
4523 }
4624
4725 static var frontmostXcodeWindowIsEditor : ( ) async -> Bool = {
@@ -93,58 +71,37 @@ enum Environment {
9371 }
9472
9573 static var fetchCurrentFileURL : ( ) async throws -> URL = {
96- var activeXcodes = [ NSRunningApplication] ( )
97- var retryCount = 0
98- // Sometimes runningApplications returns 0 items.
99- while activeXcodes. isEmpty, retryCount < 5 {
100- activeXcodes = NSRunningApplication
101- . runningApplications ( withBundleIdentifier: " com.apple.dt.Xcode " )
102- . sorted { lhs, _ in
103- if lhs. isActive { return true }
104- return false
105- }
106- if retryCount > 0 { try await Task . sleep ( nanoseconds: 10_000_000 ) }
107- retryCount += 1
74+ guard let xcode = ActiveApplicationMonitor . activeXcode else {
75+ throw FailedToFetchFileURLError ( )
10876 }
10977
11078 // fetch file path of the frontmost window of Xcode through Accessability API.
111- for xcode in activeXcodes {
112- let application = AXUIElementCreateApplication ( xcode. processIdentifier)
113- do {
114- let frontmostWindow = try application. copyValue (
115- key: kAXFocusedWindowAttribute,
116- ofType: AXUIElement . self
117- )
118- var path = try ? frontmostWindow. copyValue (
119- key: kAXDocumentAttribute,
120- ofType: String ? . self
121- )
122- if path == nil {
123- for window in try application. copyValue (
124- key: kAXWindowsAttribute,
125- ofType: [ AXUIElement ] . self
126- ) {
127- path = try ? window. copyValue (
128- key: kAXDocumentAttribute,
129- ofType: String ? . self
130- )
131- if path != nil { break }
132- }
133- }
134- if let path = path? . removingPercentEncoding {
135- let url = URL (
136- fileURLWithPath: path
137- . replacingOccurrences ( of: " file:// " , with: " " )
138- )
139- return url
140- }
141- } catch {
142- if let axError = error as? AXError , axError == . apiDisabled {
143- throw NoAccessToAccessibilityAPIError ( )
79+ let application = AXUIElementCreateApplication ( xcode. processIdentifier)
80+ do {
81+ let frontmostWindow : AXUIElement = try application
82+ . copyValue ( key: kAXFocusedWindowAttribute)
83+ var path : String ? = try ? frontmostWindow. copyValue ( key: kAXDocumentAttribute)
84+ if path == nil {
85+ for window in try application. copyValue (
86+ key: kAXWindowsAttribute,
87+ ofType: [ AXUIElement ] . self
88+ ) {
89+ path = try ? window. copyValue ( key: kAXDocumentAttribute)
90+ if path != nil { break }
14491 }
14592 }
93+ if let path = path? . removingPercentEncoding {
94+ let url = URL (
95+ fileURLWithPath: path
96+ . replacingOccurrences ( of: " file:// " , with: " " )
97+ )
98+ return url
99+ }
100+ } catch {
101+ if let axError = error as? AXError , axError == . apiDisabled {
102+ throw NoAccessToAccessibilityAPIError ( )
103+ }
146104 }
147-
148105 throw FailedToFetchFileURLError ( )
149106 }
150107
0 commit comments