forked from intitni/CopilotForXcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPromptToCodeCustomization.swift
More file actions
117 lines (102 loc) · 3.67 KB
/
PromptToCodeCustomization.swift
File metadata and controls
117 lines (102 loc) · 3.67 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
import ChatBasic
import ComposableArchitecture
import Dependencies
import Foundation
import ModificationBasic
import SuggestionBasic
import SwiftUI
public enum PromptToCodeCustomization {
public static var CustomizedUI: any PromptToCodeCustomizedUI = NoPromptToCodeCustomizedUI()
public static var contextInputControllerFactory: (
Shared<ModificationState>
) -> PromptToCodeContextInputController = { _ in
DefaultPromptToCodeContextInputController()
}
}
public struct PromptToCodeCustomizationContextWrapper<Content: View>: View {
@State var context: AnyObject
let content: (AnyObject) -> Content
public init<O: AnyObject>(context: O, @ViewBuilder content: @escaping (O) -> Content) {
self.context = context
self.content = { context in
content(context as! O)
}
}
public var body: some View {
content(context)
}
}
public protocol PromptToCodeCustomizedUI {
typealias PromptToCodeCustomizedViews = (
extraMenuItems: AnyView?,
extraButtons: AnyView?,
extraAcceptButtonVariants: AnyView?,
contextInputField: AnyView?
)
func callAsFunction<V: View>(
state: Shared<ModificationState>,
delegate: PromptToCodeContextInputControllerDelegate,
contextInputController: PromptToCodeContextInputController,
isInputFieldFocused: FocusState<Bool>,
@ViewBuilder view: @escaping (PromptToCodeCustomizedViews) -> V
) -> PromptToCodeCustomizationContextWrapper<V>
}
public protocol PromptToCodeContextInputControllerDelegate {
func modifyCodeButtonClicked()
}
public protocol PromptToCodeContextInputController: Perception.Perceptible {
var instruction: NSAttributedString { get set }
func resolveContext(onStatusChange: @escaping ([String]) async -> Void) async -> (
instruction: String,
references: [ChatMessage.Reference],
topics: [ChatMessage.Reference],
agent: (() -> any ModificationAgent)?
)
}
struct NoPromptToCodeCustomizedUI: PromptToCodeCustomizedUI {
private class Context {}
func callAsFunction<V: View>(
state: Shared<ModificationState>,
delegate: PromptToCodeContextInputControllerDelegate,
contextInputController: PromptToCodeContextInputController,
isInputFieldFocused: FocusState<Bool>,
@ViewBuilder view: @escaping (PromptToCodeCustomizedViews) -> V
) -> PromptToCodeCustomizationContextWrapper<V> {
PromptToCodeCustomizationContextWrapper(context: Context()) { _ in
view((
extraMenuItems: nil,
extraButtons: nil,
extraAcceptButtonVariants: nil,
contextInputField: nil
))
}
}
}
@Perceptible
public final class DefaultPromptToCodeContextInputController: PromptToCodeContextInputController {
public var instruction: NSAttributedString = .init()
public var instructionString: String {
get { instruction.string }
set { instruction = .init(string: newValue) }
}
public func appendNewLineToPromptButtonTapped() {
let mutable = NSMutableAttributedString(
attributedString: instruction
)
mutable.append(NSAttributedString(string: "\n"))
instruction = mutable
}
public func resolveContext(onStatusChange: @escaping ([String]) async -> Void) -> (
instruction: String,
references: [ChatMessage.Reference],
topics: [ChatMessage.Reference],
agent: (() -> any ModificationAgent)?
) {
return (
instruction: instructionString,
references: [],
topics: [],
agent: nil
)
}
}