forked from intitni/CopilotForXcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWidgetDataSource.swift
More file actions
121 lines (112 loc) · 4.45 KB
/
WidgetDataSource.swift
File metadata and controls
121 lines (112 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import ChatService
import Foundation
import OpenAIService
import SuggestionWidget
final class WidgetDataSource {
static let shared = WidgetDataSource()
var globalChat: ChatService?
var chats = [URL: ChatService]()
var globalChatProvider: ChatProvider?
var chatProviders = [URL: ChatProvider]()
private init() {}
@discardableResult
func createChatIfNeeded(for url: URL) -> ChatService {
let useGlobalChat = UserDefaults.shared.value(for: \.useGlobalChat)
let chat: ChatService
if useGlobalChat {
chat = globalChat ?? ChatService(chatGPTService: ChatGPTService())
globalChat = chat
} else {
chat = chats[url] ?? ChatService(chatGPTService: ChatGPTService())
chats[url] = chat
}
return chat
}
}
extension WidgetDataSource: SuggestionWidgetDataSource {
func suggestionForFile(at url: URL) async -> SuggestionProvider? {
for workspace in await workspaces.values {
if let filespace = await workspace.filespaces[url],
let suggestion = await filespace.presentingSuggestion
{
return .init(
code: suggestion.text,
language: await filespace.language,
startLineIndex: suggestion.position.line,
suggestionCount: await filespace.suggestions.count,
currentSuggestionIndex: await filespace.suggestionIndex,
onSelectPreviousSuggestionTapped: {
Task { @ServiceActor in
let handler = PseudoCommandHandler()
await handler.presentPreviousSuggestion()
}
},
onSelectNextSuggestionTapped: {
Task { @ServiceActor in
let handler = PseudoCommandHandler()
await handler.presentNextSuggestion()
}
},
onRejectSuggestionTapped: {
Task { @ServiceActor in
let handler = PseudoCommandHandler()
await handler.rejectSuggestions()
}
},
onAcceptSuggestionTapped: {
Task { @ServiceActor in
let handler = PseudoCommandHandler()
await handler.acceptSuggestion()
}
}
)
}
}
return nil
}
func chatForFile(at url: URL) async -> ChatProvider? {
let useGlobalChat = UserDefaults.shared.value(for: \.useGlobalChat)
let buildChatProvider = { (service: ChatService) in
ChatProvider(
service: service,
fileURL: url,
onCloseChat: { [weak self] in
if UserDefaults.shared.value(for: \.useGlobalChat) {
self?.globalChat = nil
self?.globalChatProvider = nil
} else {
self?.chats[url] = nil
self?.chatProviders[url] = nil
}
let presenter = PresentInWindowSuggestionPresenter()
presenter.closeChatRoom(fileURL: url)
},
onSwitchContext: { [weak self] in
let useGlobalChat = UserDefaults.shared.value(for: \.useGlobalChat)
UserDefaults.shared.set(!useGlobalChat, for: \.useGlobalChat)
self?.createChatIfNeeded(for: url)
let presenter = PresentInWindowSuggestionPresenter()
presenter.presentChatRoom(fileURL: url)
}
)
}
if useGlobalChat {
if let globalChatProvider {
return globalChatProvider
} else if let globalChat {
let new = buildChatProvider(globalChat)
self.globalChatProvider = new
return new
}
} else {
if let provider = chatProviders[url] {
return provider
} else if let service = chats[url] {
let new = buildChatProvider(service)
self.chatProviders[url] = new
return new
}
}
return nil
}
}