Skip to content

Commit 0f6d469

Browse files
committed
Merge branch 'release/0.13.1'
2 parents 42741a4 + 21bcbac commit 0f6d469

14 files changed

+186
-55
lines changed

Copilot for Xcode/CustomCommandView.swift

+59-14
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,10 @@ struct EditCustomCommandView: View {
176176
self.systemPrompt = systemPrompt ?? ""
177177
self.prompt = prompt ?? ""
178178
continuousMode = false
179-
case let .promptToCode(prompt, continuousMode):
179+
case let .promptToCode(extraSystemPrompt, prompt, continuousMode):
180180
commandType = .promptToCode
181181
self.prompt = prompt ?? ""
182-
systemPrompt = ""
182+
systemPrompt = extraSystemPrompt ?? ""
183183
self.continuousMode = continuousMode ?? false
184184
case .none:
185185
commandType = .chatWithSelection
@@ -214,6 +214,7 @@ struct EditCustomCommandView: View {
214214
systemPromptTextField(title: "Extra System Prompt")
215215
promptTextField
216216
case .promptToCode:
217+
systemPromptTextField(title: "Extra System Prompt")
217218
promptTextField
218219
continuousModeToggle
219220
case .customChat:
@@ -244,7 +245,11 @@ struct EditCustomCommandView: View {
244245
prompt: prompt
245246
)
246247
case .promptToCode:
247-
return .promptToCode(prompt: prompt, continuousMode: continuousMode)
248+
return .promptToCode(
249+
extraSystemPrompt: systemPrompt,
250+
prompt: prompt,
251+
continuousMode: continuousMode
252+
)
248253
case .customChat:
249254
return .customChat(systemPrompt: systemPrompt, prompt: prompt)
250255
}
@@ -297,24 +302,40 @@ struct EditCustomCommandView: View {
297302
.frame(width: 600)
298303
}
299304

305+
@ViewBuilder
300306
var promptTextField: some View {
301-
if #available(macOS 13.0, *) {
302-
return TextField("Prompt", text: $prompt, axis: .vertical)
307+
VStack(alignment: .leading, spacing: 4) {
308+
Text("Prompt")
309+
TextEditor(text: $prompt)
310+
.font(Font.system(.body, design: .monospaced))
311+
.padding(2)
312+
.frame(minHeight: 120)
303313
.multilineTextAlignment(.leading)
304-
.lineLimit(4, reservesSpace: true)
305-
} else {
306-
return TextField("Prompt", text: $prompt)
314+
.overlay(
315+
RoundedRectangle(cornerRadius: 1)
316+
.stroke(.black, lineWidth: 1 / 3)
317+
.opacity(0.3)
318+
)
307319
}
320+
.padding(.vertical, 4)
308321
}
309322

323+
@ViewBuilder
310324
func systemPromptTextField(title: String? = nil) -> some View {
311-
if #available(macOS 13.0, *) {
312-
return TextField(title ?? "System Prompt", text: $systemPrompt, axis: .vertical)
325+
VStack(alignment: .leading, spacing: 4) {
326+
Text(title ?? "System Prompt")
327+
TextEditor(text: $systemPrompt)
328+
.font(Font.system(.body, design: .monospaced))
329+
.padding(2)
330+
.frame(minHeight: 120)
313331
.multilineTextAlignment(.leading)
314-
.lineLimit(4, reservesSpace: true)
315-
} else {
316-
return TextField("Prompt", text: $prompt)
332+
.overlay(
333+
RoundedRectangle(cornerRadius: 1)
334+
.stroke(.black, lineWidth: 1 / 3)
335+
.opacity(0.3)
336+
)
317337
}
338+
.padding(.vertical, 4)
318339
}
319340

320341
var continuousModeToggle: some View {
@@ -335,7 +356,11 @@ struct CustomCommandView_Preview: PreviewProvider {
335356
),
336357
.init(
337358
name: "Refactor Code",
338-
feature: .promptToCode(prompt: "Refactor", continuousMode: false)
359+
feature: .promptToCode(
360+
extraSystemPrompt: nil,
361+
prompt: "Refactor",
362+
continuousMode: false
363+
)
339364
),
340365
.init(
341366
name: "Tell Me A Joke",
@@ -346,3 +371,23 @@ struct CustomCommandView_Preview: PreviewProvider {
346371
.background(.purple)
347372
}
348373
}
374+
375+
struct EditCustomCommandView_Preview: PreviewProvider {
376+
static var previews: some View {
377+
EditCustomCommandView(
378+
editingCommand: .constant(CustomCommandView.EditingCommand(
379+
isNew: false,
380+
command: .init(
381+
name: "Explain Code",
382+
feature: .promptToCode(
383+
extraSystemPrompt: nil,
384+
prompt: "Hello",
385+
continuousMode: false
386+
)
387+
)
388+
)),
389+
settings: .init(customCommands: .init(wrappedValue: [], "CustomCommandView_Preview"))
390+
)
391+
.background(.purple)
392+
}
393+
}

Copilot for Xcode/SettingsView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ struct SettingsView: View {
165165
case .openAI:
166166
Text("OpenAI").tag($0)
167167
case .githubCopilot:
168-
Text("GitHub Copilot (Less Accurate)").tag($0)
168+
Text("GitHub Copilot (Implement for experiment, barely works, don't use.)").tag($0)
169169
}
170170
}
171171
} label: {

Core/Sources/Preferences/CustomCommand.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ public struct CustomCommand: Codable {
55
///
66
/// Keep everything optional so nothing will break when the format changes.
77
public enum Feature: Codable {
8-
case promptToCode(prompt: String?, continuousMode: Bool?)
8+
case promptToCode(extraSystemPrompt: String?, prompt: String?, continuousMode: Bool?)
99
case chatWithSelection(extraSystemPrompt: String?, prompt: String?)
1010
case customChat(systemPrompt: String?, prompt: String?)
1111
}

Core/Sources/Preferences/Keys.swift

+1
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ public extension UserDefaultPreferenceKeys {
236236
.init(
237237
name: "Add Documentation to Selection",
238238
feature: .promptToCode(
239+
extraSystemPrompt: nil,
239240
prompt: "Add documentation on top of the code. Use triple slash if the language supports it.",
240241
continuousMode: false
241242
)

Core/Sources/PromptToCodeService/CopilotPromptToCodeAPI.swift

+18-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ final class CopilotPromptToCodeAPI: PromptToCodeAPI {
1818
requirement: String,
1919
projectRootURL: URL,
2020
fileURL: URL,
21-
allCode: String
21+
allCode: String,
22+
extraSystemPrompt: String?
2223
) async throws -> AsyncThrowingStream<(code: String, description: String), Error> {
2324
let copilotService = CopilotSuggestionService(projectRootURL: projectRootURL)
2425
let relativePath = {
@@ -36,14 +37,25 @@ final class CopilotPromptToCodeAPI: PromptToCodeAPI {
3637
return filePath
3738
}()
3839

39-
let comment = """
40-
// update the following code, \(requirement.split(separator: "\n").joined(separator: " ")).
41-
\(code.split(separator: "\n").map { "//\($0)" }.joined(separator: "\n"))
40+
func convertToComment(_ s: String) -> String {
41+
s.split(separator: "\n").map { "// \($0)" }.joined(separator: "\n")
42+
}
4243

44+
let comment = """
45+
// A file to refactor the following code
46+
//
47+
// Code:
48+
// ```
49+
\(convertToComment(code))
50+
// ```
51+
//
52+
// Requirements:
53+
\(convertToComment((extraSystemPrompt ?? "\n") + requirement))
54+
//
4355
4456
45-
// Path: \(relativePath)
4657
58+
// end of file
4759
"""
4860
let lineCount = comment.breakLines().count
4961

@@ -53,7 +65,7 @@ final class CopilotPromptToCodeAPI: PromptToCodeAPI {
5365
let result = try await copilotService.getCompletions(
5466
fileURL: fileURL,
5567
content: comment,
56-
cursorPosition: .init(line: lineCount - 4, character: 0),
68+
cursorPosition: .init(line: lineCount - 3, character: 0),
5769
tabSize: indentSize,
5870
indentSize: indentSize,
5971
usesTabsForIndentation: usesTabsForIndentation,

Core/Sources/PromptToCodeService/OpenAIPromptToCodeAPI.swift

+15-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ final class OpenAIPromptToCodeAPI: PromptToCodeAPI {
2020
requirement: String,
2121
projectRootURL: URL,
2222
fileURL: URL,
23-
allCode: String
23+
allCode: String,
24+
extraSystemPrompt: String?
2425
) async throws -> AsyncThrowingStream<(code: String, description: String), Error> {
2526
let userPreferredLanguage = UserDefaults.shared.value(for: \.chatGPTLanguage)
2627
let textLanguage = userPreferredLanguage.isEmpty ? "" : "in \(userPreferredLanguage)"
@@ -30,6 +31,10 @@ final class OpenAIPromptToCodeAPI: PromptToCodeAPI {
3031
if code.isEmpty {
3132
return """
3233
You are a senior programer in writing code in \(language.rawValue).
34+
35+
File url: \(fileURL)
36+
37+
\(extraSystemPrompt ?? "")
3338
3439
Please write a piece of code that meets my requirements. The indentation should be \(
3540
indentRule
@@ -41,22 +46,30 @@ final class OpenAIPromptToCodeAPI: PromptToCodeAPI {
4146
"""
4247
} else {
4348
return """
49+
# Description
50+
4451
You are a senior programer in writing code in \(language.rawValue).
52+
53+
File url: \(fileURL)
54+
55+
\(extraSystemPrompt ?? "")
4556
4657
Please mutate the following code fragment with my requirements. Keep the original indentation. Do not add comments unless told to.
4758
4859
Please reply to me start with the code block followed by a clear and concise description about what you did in 1-3 sentences \(
4960
textLanguage
5061
).
5162
63+
# Code
64+
5265
```
5366
\(code)
5467
```
5568
"""
5669
}
5770
}()
5871

59-
let chatGPTService = ChatGPTService(systemPrompt: prompt, temperature: 0.5)
72+
let chatGPTService = ChatGPTService(systemPrompt: prompt, temperature: 0.3)
6073
service = chatGPTService
6174
let stream = try await chatGPTService.send(content: requirement)
6275
return .init { continuation in

Core/Sources/PromptToCodeService/PromptToCodeService.swift

+8-3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public final class PromptToCodeService: ObservableObject {
5353
public var projectRootURL: URL
5454
public var fileURL: URL
5555
public var allCode: String
56+
public var extraSystemPrompt: String?
5657

5758
public init(
5859
code: String,
@@ -62,7 +63,8 @@ public final class PromptToCodeService: ObservableObject {
6263
usesTabsForIndentation: Bool,
6364
projectRootURL: URL,
6465
fileURL: URL,
65-
allCode: String
66+
allCode: String,
67+
extraSystemPrompt: String? = nil
6668
) {
6769
self.code = code
6870
self.selectionRange = selectionRange
@@ -73,6 +75,7 @@ public final class PromptToCodeService: ObservableObject {
7375
self.fileURL = fileURL
7476
self.allCode = allCode
7577
self.history = .empty
78+
self.extraSystemPrompt = extraSystemPrompt
7679
}
7780

7881
public func modifyCode(prompt: String) async throws {
@@ -93,7 +96,8 @@ public final class PromptToCodeService: ObservableObject {
9396
requirement: prompt,
9497
projectRootURL: projectRootURL,
9598
fileURL: fileURL,
96-
allCode: allCode
99+
allCode: allCode,
100+
extraSystemPrompt: extraSystemPrompt
97101
)
98102
for try await fragment in stream {
99103
code = fragment.code
@@ -145,7 +149,8 @@ protocol PromptToCodeAPI {
145149
requirement: String,
146150
projectRootURL: URL,
147151
fileURL: URL,
148-
allCode: String
152+
allCode: String,
153+
extraSystemPrompt: String?
149154
) async throws -> AsyncThrowingStream<(code: String, description: String), Error>
150155

151156
func stopResponding()

Core/Sources/Service/GUI/PromptToCodeProvider+Service.swift

+10-5
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@ import PromptToCodeService
33
import SuggestionWidget
44

55
extension PromptToCodeProvider {
6-
convenience init(service: PromptToCodeService, onClosePromptToCode: @escaping () -> Void) {
6+
convenience init(
7+
service: PromptToCodeService,
8+
name: String?,
9+
onClosePromptToCode: @escaping () -> Void
10+
) {
711
self.init(
812
code: service.code,
913
language: service.language.rawValue,
1014
description: "",
1115
startLineIndex: service.selectionRange.start.line,
12-
startLineColumn: service.selectionRange.start.character
16+
startLineColumn: service.selectionRange.start.character,
17+
name: name
1318
)
1419

1520
var cancellables = Set<AnyCancellable>()
@@ -44,18 +49,18 @@ extension PromptToCodeProvider {
4449
}
4550
}
4651
}
47-
52+
4853
onStopRespondingTap = {
4954
service.stopResponding()
5055
}
51-
56+
5257
onAcceptSuggestionTapped = {
5358
Task { @ServiceActor in
5459
let handler = PseudoCommandHandler()
5560
await handler.acceptSuggestion()
5661
}
5762
}
58-
63+
5964
onContinuousToggleClick = {
6065
service.isContinuous.toggle()
6166
}

Core/Sources/Service/GUI/WidgetDataSource.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ final class WidgetDataSource {
9191
selectionRange: CursorRange,
9292
language: CopilotLanguage,
9393
identSize: Int = 4,
94-
usesTabsForIndentation: Bool = false
94+
usesTabsForIndentation: Bool = false,
95+
extraSystemPrompt: String?,
96+
name: String?
9597
) async -> PromptToCodeService {
9698
let build = {
9799
let service = PromptToCodeService(
@@ -102,10 +104,12 @@ final class WidgetDataSource {
102104
usesTabsForIndentation: usesTabsForIndentation,
103105
projectRootURL: projectURL,
104106
fileURL: url,
105-
allCode: allCode
107+
allCode: allCode,
108+
extraSystemPrompt: extraSystemPrompt
106109
)
107110
let provider = PromptToCodeProvider(
108111
service: service,
112+
name: name,
109113
onClosePromptToCode: { [weak self] in
110114
self?.removePromptToCode(for: url)
111115
let presenter = PresentInWindowSuggestionPresenter()

0 commit comments

Comments
 (0)