forked from intitni/CopilotForXcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDynamicContextController.swift
More file actions
90 lines (80 loc) · 3.09 KB
/
DynamicContextController.swift
File metadata and controls
90 lines (80 loc) · 3.09 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
import Foundation
import OpenAIService
import SuggestionModel
import XcodeInspector
import Preferences
final class DynamicContextController {
let chatGPTService: any ChatGPTServiceType
init(chatGPTService: any ChatGPTServiceType) {
self.chatGPTService = chatGPTService
}
func updatePromptToMatchContent(systemPrompt: String) async throws {
let language = UserDefaults.shared.value(for: \.chatGPTLanguage)
let content = getEditorInformation()
let relativePath = content.documentURL.path
.replacingOccurrences(of: content.projectURL.path, with: "")
let selectionRange = content.editorContent?.selections.first ?? .outOfScope
let contextualSystemPrompt = """
\(language.isEmpty ? "" : "You must always reply in \(language)")
\(systemPrompt)
Active Document Context:###
Document Relative Path: \(relativePath)
Selection Range Start: \
Line \(selectionRange.start.line) \
Character \(selectionRange.start.character)
Selection Range End: \
Line \(selectionRange.end.line) \
Character \(selectionRange.end.character)
Cursor Position: \
Line \(selectionRange.end.line) \
Character \(selectionRange.end.character)
Selected Code (start from line \(selectionRange.end.line)):```\(content.language.rawValue)
\(content.selectedContent)
```
Line Annotations:
\(content.editorContent?.lineAnnotations.map { "- \($0)" }.joined(separator: "\n") ?? "N/A")
###
"""
await chatGPTService.mutateSystemPrompt(contextualSystemPrompt)
}
}
extension DynamicContextController {
struct Information {
let editorContent: SourceEditor.Content?
let selectedContent: String
let documentURL: URL
let projectURL: URL
let language: CodeLanguage
}
func getEditorInformation() -> Information {
let editorContent = XcodeInspector.shared.focusedEditor?.content
let documentURL = XcodeInspector.shared.activeDocumentURL
let projectURL = XcodeInspector.shared.activeProjectURL
let language = languageIdentifierFromFileURL(documentURL)
if let editorContent, let range = editorContent.selections.first {
let startIndex = min(
max(0, range.start.line),
editorContent.lines.endIndex - 1
)
let endIndex = min(
max(startIndex, range.end.line),
editorContent.lines.endIndex - 1
)
let selectedContent = editorContent.lines[startIndex...endIndex]
return .init(
editorContent: editorContent,
selectedContent: selectedContent.joined(),
documentURL: documentURL,
projectURL: projectURL,
language: language
)
}
return .init(
editorContent: editorContent,
selectedContent: "",
documentURL: documentURL,
projectURL: projectURL,
language: language
)
}
}