Skip to content

Commit 5551e1f

Browse files
committed
Update open mode to better handle builtin extensions
1 parent 603ddfd commit 5551e1f

File tree

6 files changed

+75
-13
lines changed

6 files changed

+75
-13
lines changed

Core/Sources/Service/GUI/GraphicalUserInterfaceController.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,14 @@ extension ChatTabPool {
373373
) async -> (any ChatTab, ChatTabInfo)? {
374374
let id = UUID().uuidString
375375
let info = ChatTabInfo(id: id, title: "")
376-
let builder = kind?.builder ?? ChatGPTChatTab.defaultBuilder()
376+
let builder = kind?.builder ?? {
377+
for ext in BuiltinExtensionManager.shared.extensions {
378+
guard let tab = ext.chatTabTypes.first(where: { $0.isDefaultChatTabReplacement } )
379+
else { continue }
380+
return tab.defaultChatBuilder()
381+
}
382+
return ChatGPTChatTab.defaultBuilder()
383+
}()
377384
guard let chatTap = await builder.build(store: createStore(id)) else { return nil }
378385
setTab(chatTap)
379386
return (chatTap, info)

Core/Sources/Service/SuggestionCommandHandler/PseudoCommandHandler.swift

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ActiveApplicationMonitor
22
import AppKit
3+
import BuiltinExtension
34
import CodeiumService
45
import CommandHandler
56
import enum CopilotForXcodeKit.SuggestionServiceError
@@ -218,12 +219,12 @@ struct PseudoCommandHandler: CommandHandler {
218219
if now.timeIntervalSince(last) > 60 * 60 {
219220
Self.lastTimeCommandFailedToTriggerWithAccessibilityAPI = now
220221
toast.toast(content: """
221-
The app is using a fallback solution to accept suggestions. \
222-
For better experience, please restart Xcode to re-activate the Copilot \
223-
menu item.
224-
""", type: .warning)
222+
The app is using a fallback solution to accept suggestions. \
223+
For better experience, please restart Xcode to re-activate the Copilot \
224+
menu item.
225+
""", type: .warning)
225226
}
226-
227+
227228
throw error
228229
}
229230
}
@@ -340,6 +341,24 @@ struct PseudoCommandHandler: CommandHandler {
340341
func openChat(forceDetach: Bool, activateThisApp: Bool = true) {
341342
switch UserDefaults.shared.value(for: \.openChatMode) {
342343
case .chatPanel:
344+
for ext in BuiltinExtensionManager.shared.extensions {
345+
guard let tab = ext.chatTabTypes.first(where: { $0.isDefaultChatTabReplacement } )
346+
else { continue }
347+
Task { @MainActor in
348+
let store = Service.shared.guiController.store
349+
await store.send(
350+
.createAndSwitchToChatTabIfNeededMatching(
351+
check: { $0.name == tab.name },
352+
kind: .init(tab.defaultChatBuilder())
353+
)
354+
).finish()
355+
store.send(.openChatPanel(
356+
forceDetach: forceDetach,
357+
activateThisApp: activateThisApp
358+
))
359+
}
360+
return
361+
}
343362
Task { @MainActor in
344363
let store = Service.shared.guiController.store
345364
await store.send(.createAndSwitchToChatGPTChatTabIfNeeded).finish()
@@ -395,20 +414,26 @@ struct PseudoCommandHandler: CommandHandler {
395414
await openURL(url)
396415
}
397416
}
398-
case .codeiumChat:
417+
case let .builtinExtension(extensionIdentifier, tabName):
418+
guard let ext = BuiltinExtensionManager.shared.extensions
419+
.first(where: { $0.extensionIdentifier == extensionIdentifier }),
420+
let tab = ext.chatTabTypes.first(where: { $0.name == tabName })
421+
else { return }
399422
Task { @MainActor in
400423
let store = Service.shared.guiController.store
401424
await store.send(
402425
.createAndSwitchToChatTabIfNeededMatching(
403-
check: { $0 is CodeiumChatTab },
404-
kind: .init(CodeiumChatTab.defaultChatBuilder())
426+
check: { $0.name == tabName },
427+
kind: .init(tab.defaultChatBuilder())
405428
)
406429
).finish()
407430
store.send(.openChatPanel(
408431
forceDetach: forceDetach,
409432
activateThisApp: activateThisApp
410433
))
411434
}
435+
case let .externalExtension(extensionIdentifier, tabName):
436+
return
412437
}
413438
}
414439

Tool/Sources/ChatTab/ChatTab.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public protocol ChatTabType {
3737
/// Available builders for this chat tab.
3838
/// It's used to generate a list of tab types for user to create.
3939
static func chatBuilders() -> [ChatTabBuilder]
40+
/// The default chat tab builder to be used in open chat
41+
static func defaultChatBuilder() -> ChatTabBuilder
4042
/// Restorable state
4143
func restorableState() async -> Data
4244
/// Restore state
@@ -179,6 +181,9 @@ public extension ChatTabType {
179181

180182
static var canHandleOpenChatCommand: Bool { false }
181183
static var isDefaultChatTabReplacement: Bool { false }
184+
static func defaultChatBuilder() -> ChatTabBuilder {
185+
DisabledChatTabBuilder(title: name)
186+
}
182187
}
183188

184189
/// A chat tab that does nothing.

Tool/Sources/Preferences/Keys.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,11 @@ public extension UserDefaultPreferenceKeys {
518518
.init(defaultValue: true, key: "KeepFloatOnTopIfChatPanelAndXcodeOverlaps")
519519
}
520520

521-
var openChatMode: PreferenceKey<OpenChatMode> {
521+
var openChatMode: PreferenceKey<UserDefaultsStorageBox<OpenChatMode>> {
522+
.init(defaultValue: .init(.chatPanel), key: "DefaultOpenChatMode")
523+
}
524+
525+
var legacyOpenChatMode: DeprecatedPreferenceKey<OpenChatMode.LegacyOpenChatMode> {
522526
.init(defaultValue: .chatPanel, key: "OpenChatMode")
523527
}
524528

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import Foundation
22

3-
public enum OpenChatMode: String, CaseIterable {
3+
public enum OpenChatMode: Codable, Equatable {
4+
public enum LegacyOpenChatMode: String {
5+
case chatPanel
6+
case browser
7+
case codeiumChat
8+
}
9+
410
case chatPanel
511
case browser
6-
case codeiumChat
12+
case builtinExtension(extensionIdentifier: String, tabName: String)
13+
case externalExtension(extensionIdentifier: String, tabName: String)
714
}

Tool/Sources/Preferences/UserDefaults.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ public extension UserDefaults {
5151
weight: .regular
5252
)))
5353
)
54+
shared.setupDefaultValue(
55+
for: \.openChatMode,
56+
defaultValue: {
57+
switch shared.deprecatedValue(for: \.legacyOpenChatMode) {
58+
case .chatPanel: return .init(.chatPanel)
59+
case .browser: return .init(.browser)
60+
case .codeiumChat:
61+
return .init(.builtinExtension(
62+
extensionIdentifier: "com.codeium",
63+
tabName: "Codeium Chat"
64+
))
65+
}
66+
}()
67+
)
5468
}
5569
}
5670

@@ -65,7 +79,7 @@ extension String: UserDefaultsStorable {}
6579
extension Data: UserDefaultsStorable {}
6680
extension URL: UserDefaultsStorable {}
6781

68-
extension Array: RawRepresentable where Element: Codable {
82+
extension Array: @retroactive RawRepresentable where Element: Codable {
6983
public init?(rawValue: String) {
7084
guard let data = rawValue.data(using: .utf8),
7185
let result = try? JSONDecoder().decode([Element].self, from: data)

0 commit comments

Comments
 (0)