Skip to content

Commit 5714f64

Browse files
committed
Add toggle "Use accessibility API to accept suggestion in widget"
1 parent 585f37b commit 5714f64

3 files changed

Lines changed: 70 additions & 50 deletions

File tree

Copilot for Xcode/SettingsView.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ final class Settings: ObservableObject {
1515
var suggestionWidgetPositionMode: SuggestionWidgetPositionMode
1616
@AppStorage(\.widgetColorScheme)
1717
var widgetColorScheme: WidgetColorScheme
18+
@AppStorage(\.acceptSuggestionWithAccessibilityAPI)
19+
var acceptSuggestionWithAccessibilityAPI: Bool
1820
init() {}
1921
}
2022

@@ -107,6 +109,11 @@ struct SettingsView: View {
107109
.fill(Color.white.opacity(0.2))
108110
)
109111
}
112+
113+
Toggle(isOn: $settings.acceptSuggestionWithAccessibilityAPI) {
114+
Text("Use accessibility API to accept suggestion in widget")
115+
}
116+
.toggleStyle(.switch)
110117
}
111118
}.buttonStyle(.copilot)
112119
}

Core/Sources/Preferences/Keys.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ public struct UserDefaultPreferenceKeys {
100100

101101
public var chatGPTLanguage: ChatGPTLanguage { .init() }
102102

103+
public struct AcceptSuggestionWithAccessibilityAPI: UserDefaultPreferenceKey {
104+
public let defaultValue = false
105+
public let key = "AcceptSuggestionWithAccessibilityAPI"
106+
}
107+
108+
public var acceptSuggestionWithAccessibilityAPI: AcceptSuggestionWithAccessibilityAPI {
109+
.init()
110+
}
111+
103112
public var disableLazyVStack: FeatureFlags.DisableLazyVStack { .init() }
104113
}
105114

Core/Sources/Service/SuggestionCommandHandler/PseudoCommandHandler.swift

Lines changed: 54 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -70,63 +70,67 @@ struct PseudoCommandHandler {
7070
}
7171

7272
func acceptSuggestion() async {
73-
do {
74-
try await Environment.triggerAction("Accept Suggestion")
75-
return
76-
} catch {
77-
PresentInWindowSuggestionPresenter().presentError(error)
78-
}
79-
guard let xcode = ActiveApplicationMonitor.activeXcode else { return }
80-
let application = AXUIElementCreateApplication(xcode.processIdentifier)
81-
guard let focusElement = application.focusedElement,
82-
focusElement.description == "Source Editor"
83-
else { return }
84-
guard let (content, lines, cursorPosition) = await getFileContent() else {
85-
PresentInWindowSuggestionPresenter().presentErrorMessage("Unable to get file content.")
86-
return
87-
}
88-
let handler = CommentBaseCommandHandler()
89-
do {
90-
guard let result = try await handler.acceptSuggestion(editor: .init(
91-
content: content,
92-
lines: lines,
93-
uti: "",
94-
cursorPosition: cursorPosition,
95-
selections: [],
96-
tabSize: 0,
97-
indentSize: 0,
98-
usesTabsForIndentation: false
99-
)) else { return }
100-
101-
let oldPosition = focusElement.selectedTextRange
102-
103-
let error = AXUIElementSetAttributeValue(
104-
focusElement,
105-
kAXValueAttribute as CFString,
106-
result.content as CFTypeRef
107-
)
108-
109-
if error != AXError.success {
73+
if UserDefaults.shared.value(for: \.acceptSuggestionWithAccessibilityAPI) {
74+
guard let xcode = ActiveApplicationMonitor.activeXcode else { return }
75+
let application = AXUIElementCreateApplication(xcode.processIdentifier)
76+
guard let focusElement = application.focusedElement,
77+
focusElement.description == "Source Editor"
78+
else { return }
79+
guard let (content, lines, cursorPosition) = await getFileContent() else {
11080
PresentInWindowSuggestionPresenter()
111-
.presentErrorMessage("Fail to set editor content.")
81+
.presentErrorMessage("Unable to get file content.")
82+
return
11283
}
84+
let handler = CommentBaseCommandHandler()
85+
do {
86+
guard let result = try await handler.acceptSuggestion(editor: .init(
87+
content: content,
88+
lines: lines,
89+
uti: "",
90+
cursorPosition: cursorPosition,
91+
selections: [],
92+
tabSize: 0,
93+
indentSize: 0,
94+
usesTabsForIndentation: false
95+
)) else { return }
96+
97+
let oldPosition = focusElement.selectedTextRange
11398

114-
if let oldPosition {
115-
var range = CFRange(
116-
location: oldPosition.lowerBound,
117-
length: oldPosition.upperBound
99+
let error = AXUIElementSetAttributeValue(
100+
focusElement,
101+
kAXValueAttribute as CFString,
102+
result.content as CFTypeRef
118103
)
119-
if let value = AXValueCreate(.cfRange, &range) {
120-
AXUIElementSetAttributeValue(
121-
focusElement,
122-
kAXSelectedTextRangeAttribute as CFString,
123-
value
104+
105+
if error != AXError.success {
106+
PresentInWindowSuggestionPresenter()
107+
.presentErrorMessage("Fail to set editor content.")
108+
}
109+
110+
if let oldPosition {
111+
var range = CFRange(
112+
location: oldPosition.lowerBound,
113+
length: 0
124114
)
115+
if let value = AXValueCreate(.cfRange, &range) {
116+
AXUIElementSetAttributeValue(
117+
focusElement,
118+
kAXSelectedTextRangeAttribute as CFString,
119+
value
120+
)
121+
}
125122
}
126-
}
127123

128-
} catch {
129-
PresentInWindowSuggestionPresenter().presentError(error)
124+
} catch {
125+
PresentInWindowSuggestionPresenter().presentError(error)
126+
}
127+
} else {
128+
do {
129+
try await Environment.triggerAction("Accept Suggestion")
130+
return
131+
} catch {
132+
PresentInWindowSuggestionPresenter().presentError(error)
133+
}
130134
}
131135
}
132136
}

0 commit comments

Comments
 (0)