Skip to content

Commit acd7965

Browse files
committed
Merge branch 'feature/prompt-to-code-detach' into develop
2 parents 2c7664c + e8b8fbd commit acd7965

42 files changed

Lines changed: 1544 additions & 1064 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Copilot for Xcode.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
C8009BFF2941C551007AA7E8 /* ToggleRealtimeSuggestionsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8009BFE2941C551007AA7E8 /* ToggleRealtimeSuggestionsCommand.swift */; };
1111
C8009C032941C576007AA7E8 /* RealtimeSuggestionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8009C022941C576007AA7E8 /* RealtimeSuggestionCommand.swift */; };
1212
C800DBB1294C624D00B04CAC /* PrefetchSuggestionsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800DBB0294C624D00B04CAC /* PrefetchSuggestionsCommand.swift */; };
13+
C80FFB962A95F58200704A25 /* AcceptPromptToCodeCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80FFB952A95F58200704A25 /* AcceptPromptToCodeCommand.swift */; };
1314
C81291D72994FE6900196E12 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C81291D52994FE6900196E12 /* Main.storyboard */; };
1415
C814588F2939EFDC00135263 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C814588E2939EFDC00135263 /* Cocoa.framework */; };
1516
C81458942939EFDC00135263 /* SourceEditorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C81458932939EFDC00135263 /* SourceEditorExtension.swift */; };
@@ -139,6 +140,7 @@
139140
C8009BFE2941C551007AA7E8 /* ToggleRealtimeSuggestionsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleRealtimeSuggestionsCommand.swift; sourceTree = "<group>"; };
140141
C8009C022941C576007AA7E8 /* RealtimeSuggestionCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealtimeSuggestionCommand.swift; sourceTree = "<group>"; };
141142
C800DBB0294C624D00B04CAC /* PrefetchSuggestionsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefetchSuggestionsCommand.swift; sourceTree = "<group>"; };
143+
C80FFB952A95F58200704A25 /* AcceptPromptToCodeCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcceptPromptToCodeCommand.swift; sourceTree = "<group>"; };
142144
C81291D52994FE6900196E12 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
143145
C81291D92994FE7900196E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
144146
C814588C2939EFDC00135263 /* Copilot.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Copilot.appex; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -241,6 +243,7 @@
241243
C8520300293C4D9000460097 /* Helpers.swift */,
242244
C81458952939EFDC00135263 /* GetSuggestionsCommand.swift */,
243245
C87B03A4293B261200C77EAE /* AcceptSuggestionCommand.swift */,
246+
C80FFB952A95F58200704A25 /* AcceptPromptToCodeCommand.swift */,
244247
C87B03A6293B261900C77EAE /* RejectSuggestionCommand.swift */,
245248
C87B03A8293B262600C77EAE /* NextSuggestionCommand.swift */,
246249
C87B03AA293B262E00C77EAE /* PreviousSuggestionCommand.swift */,
@@ -557,6 +560,7 @@
557560
C861A6A329E5503F005C41A3 /* PromptToCodeCommand.swift in Sources */,
558561
C8520301293C4D9000460097 /* Helpers.swift in Sources */,
559562
C8009BFF2941C551007AA7E8 /* ToggleRealtimeSuggestionsCommand.swift in Sources */,
563+
C80FFB962A95F58200704A25 /* AcceptPromptToCodeCommand.swift in Sources */,
560564
C87B03A5293B261200C77EAE /* AcceptSuggestionCommand.swift in Sources */,
561565
C87B03A9293B262600C77EAE /* NextSuggestionCommand.swift in Sources */,
562566
C87B03AB293B262E00C77EAE /* PreviousSuggestionCommand.swift in Sources */,

Copilot for Xcode.xcodeproj/xcshareddata/xcschemes/Copilot for Xcode.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
buildConfiguration = "Debug">
7777
</AnalyzeAction>
7878
<ArchiveAction
79-
buildConfiguration = "Release"
79+
buildConfiguration = "Debug"
8080
revealArchiveInOrganizer = "YES">
8181
</ArchiveAction>
8282
</Scheme>

Core/Package.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,11 @@ let package = Package(
157157
.target(
158158
name: "PromptToCodeService",
159159
dependencies: [
160+
.product(name: "FocusedCodeFinder", package: "Tool"),
160161
.product(name: "SuggestionModel", package: "Tool"),
161162
.product(name: "Environment", package: "Tool"),
162163
.product(name: "OpenAIService", package: "Tool"),
164+
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
163165
]
164166
),
165167
.testTarget(name: "PromptToCodeServiceTests", dependencies: ["PromptToCodeService"]),
@@ -226,6 +228,7 @@ let package = Package(
226228
.target(
227229
name: "SuggestionWidget",
228230
dependencies: [
231+
"PromptToCodeService",
229232
"ChatGPTChatTab",
230233
.product(name: "UserDefaultsObserver", package: "Tool"),
231234
.product(name: "SharedUIComponents", package: "Tool"),
@@ -360,12 +363,9 @@ let package = Package(
360363
name: "ActiveDocumentChatContextCollector",
361364
dependencies: [
362365
"ChatContextCollector",
363-
.product(name: "LangChain", package: "Tool"),
364366
.product(name: "OpenAIService", package: "Tool"),
365367
.product(name: "Preferences", package: "Tool"),
366-
.product(name: "ASTParser", package: "Tool"),
367-
.product(name: "SwiftSyntax", package: "swift-syntax"),
368-
.product(name: "SwiftParser", package: "swift-syntax"),
368+
.product(name: "FocusedCodeFinder", package: "Tool"),
369369
],
370370
path: "Sources/ChatContextCollectors/ActiveDocumentChatContextCollector"
371371
),

Core/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/ActiveDocumentChatContextCollector.swift

Lines changed: 1 addition & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ASTParser
22
import ChatContextCollector
3+
import FocusedCodeFinder
34
import Foundation
45
import OpenAIService
56
import Preferences
@@ -188,107 +189,3 @@ public final class ActiveDocumentChatContextCollector: ChatContextCollector {
188189
}
189190
}
190191

191-
struct ActiveDocumentContext {
192-
var filePath: String
193-
var relativePath: String
194-
var language: CodeLanguage
195-
var fileContent: String
196-
var lines: [String]
197-
var selectedCode: String
198-
var selectionRange: CursorRange
199-
var lineAnnotations: [EditorInformation.LineAnnotation]
200-
var imports: [String]
201-
202-
struct FocusedContext {
203-
var context: [String]
204-
var contextRange: CursorRange
205-
var codeRange: CursorRange
206-
var code: String
207-
var lineAnnotations: [EditorInformation.LineAnnotation]
208-
var otherLineAnnotations: [EditorInformation.LineAnnotation]
209-
}
210-
211-
var focusedContext: FocusedContext?
212-
213-
mutating func moveToFocusedCode() {
214-
moveToCodeContainingRange(selectionRange)
215-
}
216-
217-
mutating func moveToCodeAroundLine(_ line: Int) {
218-
moveToCodeContainingRange(.init(
219-
start: .init(line: line, character: 0),
220-
end: .init(line: line, character: 0)
221-
))
222-
}
223-
224-
mutating func expandFocusedRangeToContextRange() {
225-
guard let focusedContext else { return }
226-
moveToCodeContainingRange(focusedContext.contextRange)
227-
}
228-
229-
mutating func moveToCodeContainingRange(_ range: CursorRange) {
230-
let finder: FocusedCodeFinder = {
231-
switch language {
232-
case .builtIn(.swift):
233-
return SwiftFocusedCodeFinder()
234-
default:
235-
return UnknownLanguageFocusedCodeFinder(proposedSearchRange: 5)
236-
}
237-
}()
238-
239-
let codeContext = finder.findFocusedCode(
240-
containingRange: range,
241-
activeDocumentContext: self
242-
)
243-
244-
imports = codeContext.imports
245-
246-
let startLine = codeContext.focusedRange.start.line
247-
let endLine = codeContext.focusedRange.end.line
248-
var matchedAnnotations = [EditorInformation.LineAnnotation]()
249-
var otherAnnotations = [EditorInformation.LineAnnotation]()
250-
for annotation in lineAnnotations {
251-
if annotation.line >= startLine, annotation.line <= endLine {
252-
matchedAnnotations.append(annotation)
253-
} else {
254-
otherAnnotations.append(annotation)
255-
}
256-
}
257-
258-
focusedContext = .init(
259-
context: codeContext.scopeSignatures,
260-
contextRange: codeContext.contextRange,
261-
codeRange: codeContext.focusedRange,
262-
code: codeContext.focusedCode,
263-
lineAnnotations: matchedAnnotations,
264-
otherLineAnnotations: otherAnnotations
265-
)
266-
}
267-
268-
mutating func update(_ info: EditorInformation) {
269-
/// Whenever the file content, relative path, or selection range changes,
270-
/// we should reset the context.
271-
let changed: Bool = {
272-
if info.relativePath != relativePath { return true }
273-
if info.editorContent?.content != fileContent { return true }
274-
if let range = info.editorContent?.selections.first,
275-
range != selectionRange { return true }
276-
return false
277-
}()
278-
279-
filePath = info.documentURL.path
280-
relativePath = info.relativePath
281-
language = info.language
282-
fileContent = info.editorContent?.content ?? ""
283-
lines = info.editorContent?.lines ?? []
284-
selectedCode = info.selectedContent
285-
selectionRange = info.editorContent?.selections.first ?? .zero
286-
lineAnnotations = info.editorContent?.lineAnnotations ?? []
287-
imports = []
288-
289-
if changed {
290-
moveToFocusedCode()
291-
}
292-
}
293-
}
294-

Core/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/GetEditorInfo.swift

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,6 @@ import SuggestionModel
33
import XcodeInspector
44

55
func getEditorInformation() -> EditorInformation? {
6-
guard !XcodeInspector.shared.xcodes.isEmpty else { return nil }
7-
8-
let editorContent = XcodeInspector.shared.focusedEditor?.content
9-
let documentURL = XcodeInspector.shared.activeDocumentURL
10-
let projectURL = XcodeInspector.shared.activeProjectURL
11-
let language = languageIdentifierFromFileURL(documentURL)
12-
let relativePath = documentURL.path
13-
.replacingOccurrences(of: projectURL.path, with: "")
14-
15-
if let editorContent, let range = editorContent.selections.first {
16-
let (selectedContent, selectedLines) = EditorInformation.code(
17-
in: editorContent.lines,
18-
inside: range
19-
)
20-
return .init(
21-
editorContent: editorContent,
22-
selectedContent: selectedContent,
23-
selectedLines: selectedLines,
24-
documentURL: documentURL,
25-
projectURL: projectURL,
26-
relativePath: relativePath,
27-
language: language
28-
)
29-
}
30-
31-
return .init(
32-
editorContent: editorContent,
33-
selectedContent: "",
34-
selectedLines: [],
35-
documentURL: documentURL,
36-
projectURL: projectURL,
37-
relativePath: relativePath,
38-
language: language
39-
)
6+
return XcodeInspector.shared.focusedEditorContent
407
}
418

Core/Sources/Client/AsyncXPCService.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ public struct AsyncXPCService {
8585
{ $0.getRealtimeSuggestedCode }
8686
)
8787
}
88+
89+
public func getPromptToCodeAcceptedCode(editorContent: EditorContent) async throws
90+
-> UpdatedContent?
91+
{
92+
try await suggestionRequest(
93+
connection,
94+
editorContent,
95+
{ $0.getPromptToCodeAcceptedCode }
96+
)
97+
}
8898

8999
public func toggleRealtimeSuggestion() async throws {
90100
try await withXPCServiceConnected(connection: connection) {

Core/Sources/PromptToCodeService/OpenAIPromptToCodeAPI.swift renamed to Core/Sources/PromptToCodeService/OpenAIPromptToCodeService.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ import OpenAIService
33
import Preferences
44
import SuggestionModel
55

6-
final class OpenAIPromptToCodeAPI: PromptToCodeAPI {
6+
public final class OpenAIPromptToCodeService: PromptToCodeServiceType {
77
var service: (any ChatGPTServiceType)?
8+
9+
public init() {}
810

9-
func stopResponding() {
10-
Task {
11-
await service?.stopReceivingMessage()
12-
}
11+
public func stopResponding() {
12+
Task { await service?.stopReceivingMessage() }
1313
}
1414

15-
func modifyCode(
15+
public func modifyCode(
1616
code: String,
1717
language: CodeLanguage,
1818
indentSize: Int,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import Foundation
2+
import SuggestionModel
3+
4+
public final class PreviewPromptToCodeService: PromptToCodeServiceType {
5+
public init() {}
6+
7+
public func modifyCode(
8+
code: String,
9+
language: CodeLanguage,
10+
indentSize: Int,
11+
usesTabsForIndentation: Bool,
12+
requirement: String,
13+
projectRootURL: URL,
14+
fileURL: URL,
15+
allCode: String,
16+
extraSystemPrompt: String?,
17+
generateDescriptionRequirement: Bool?
18+
) async throws -> AsyncThrowingStream<(code: String, description: String), Error> {
19+
return AsyncThrowingStream { continuation in
20+
Task {
21+
let code = """
22+
struct Cat {
23+
var name: String
24+
}
25+
26+
print("Hello world!")
27+
"""
28+
let description = "I have created a struct `Cat`."
29+
var resultCode = ""
30+
var resultDescription = ""
31+
do {
32+
for character in code {
33+
try await Task.sleep(nanoseconds: 50_000_000)
34+
resultCode.append(character)
35+
continuation.yield((resultCode, resultDescription))
36+
}
37+
for character in description {
38+
try await Task.sleep(nanoseconds: 50_000_000)
39+
resultDescription.append(character)
40+
continuation.yield((resultCode, resultDescription))
41+
}
42+
continuation.finish()
43+
} catch {
44+
continuation.finish(throwing: error)
45+
}
46+
}
47+
}
48+
}
49+
50+
public func stopResponding() {}
51+
}
52+

0 commit comments

Comments
 (0)