-
-
Notifications
You must be signed in to change notification settings - Fork 427
Expand file tree
/
Copy pathGetCodeCodeAroundLineFunction.swift
More file actions
101 lines (87 loc) · 3.08 KB
/
GetCodeCodeAroundLineFunction.swift
File metadata and controls
101 lines (87 loc) · 3.08 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
import ASTParser
import ChatBasic
import Foundation
import OpenAIService
import SuggestionBasic
struct GetCodeCodeAroundLineFunction: ChatGPTFunction {
struct Arguments: Codable {
var line: Int
}
struct Result: ChatGPTFunctionResult {
var range: CursorRange
var content: String
var language: CodeLanguage
var botReadableContent: String {
"""
Code in range \(range)
```\(language.rawValue)
\(content)
```
"""
}
var userReadableContent: ChatGPTFunctionResultUserReadableContent {
.text(botReadableContent)
}
}
struct E: Error, LocalizedError {
var errorDescription: String?
}
var name: String {
"getCodeAtLine"
}
var description: String {
"Get the code at the given line. \(additionalDescription)"
}
var argumentSchema: JSONSchemaValue { [
.type: "object",
.properties: [
"line": [
.type: "number",
.description: "The line number in the file",
],
],
.required: ["line"],
] }
weak var contextCollector: ActiveDocumentChatContextCollector?
let additionalDescription: String
init(contextCollector: ActiveDocumentChatContextCollector, additionalDescription: String = "") {
self.contextCollector = contextCollector
self.additionalDescription = additionalDescription
}
func prepare(reportProgress: @escaping (String) async -> Void) async {
await reportProgress("Finding code around..")
}
func call(
arguments: Arguments,
reportProgress: @escaping (String) async -> Void
) async throws -> Result {
guard var activeDocumentContext = contextCollector?.activeDocumentContext else {
throw E(errorDescription: "No active document found.")
}
await reportProgress("Reading code around line \(arguments.line)..")
activeDocumentContext.moveToCodeAroundLine(max(arguments.line - 1, 0))
guard let newContext = activeDocumentContext.focusedContext else {
let progress = "Failed to read code around line \(arguments.line)..)"
await reportProgress(progress)
throw E(errorDescription: progress)
}
let progress = "Finish reading code at \(newContext.codeRange)"
await reportProgress(progress)
return .init(
range: newContext.codeRange,
content: newContext.code
.split(omittingEmptySubsequences: false, whereSeparator: \.isNewline)
.enumerated()
.map {
let (index, content) = $0
if index + newContext.codeRange.start.line == arguments.line - 1 {
return content + " // <--- line \(arguments.line)"
} else {
return content
}
}
.joined(separator: "\n"),
language: activeDocumentContext.language
)
}
}