Skip to content

Commit b35249d

Browse files
committed
Merge branch 'feature/completion-cheatsheet-experiment' into develop
2 parents bd8cf06 + 5d87aa7 commit b35249d

21 files changed

Lines changed: 4349 additions & 8 deletions

File tree

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@
5454
ReferencedContainer = "container:Copilot for Xcode.xcodeproj">
5555
</BuildableReference>
5656
</BuildableProductRunnable>
57+
<CommandLineArguments>
58+
<CommandLineArgument
59+
argument = "-_NS_4445425547 YES"
60+
isEnabled = "YES">
61+
</CommandLineArgument>
62+
</CommandLineArguments>
5763
</LaunchAction>
5864
<ProfileAction
5965
buildConfiguration = "Release"

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@
7171
ReferencedContainer = "container:Copilot for Xcode.xcodeproj">
7272
</BuildableReference>
7373
</BuildableProductRunnable>
74+
<CommandLineArguments>
75+
<CommandLineArgument
76+
argument = "-_NS_4445425547 YES"
77+
isEnabled = "YES">
78+
</CommandLineArgument>
79+
</CommandLineArguments>
7480
</LaunchAction>
7581
<ProfileAction
7682
buildConfiguration = "Release"

Copilot for Xcode/Copilot_for_Xcode.entitlements

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
<array>
99
<string>$(TeamIdentifierPrefix)group.$(BUNDLE_IDENTIFIER_BASE)</string>
1010
</array>
11+
<key>com.apple.security.automation.apple-events</key>
12+
<true/>
1113
<key>com.apple.security.files.user-selected.read-only</key>
1214
<true/>
1315
<key>keychain-access-groups</key>

Core/Sources/PromptToCodeService/OpenAIPromptToCodeService.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public final class OpenAIPromptToCodeService: PromptToCodeServiceType {
3737
content: source.content,
3838
lines: source.lines,
3939
selections: [source.range],
40-
cursorPosition: .outOfScope,
40+
cursorPosition: .outOfScope,
41+
cursorOffset: -1,
4142
lineAnnotations: []
4243
),
4344
selectedContent: code,

Core/Sources/Service/SuggestionCommandHandler/PseudoCommandHandler.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct PseudoCommandHandler {
2323
lines: [],
2424
uti: "",
2525
cursorPosition: .outOfScope,
26+
cursorOffset: -1,
2627
selections: [],
2728
tabSize: 0,
2829
indentSize: 0,
@@ -37,6 +38,7 @@ struct PseudoCommandHandler {
3738
lines: [],
3839
uti: "",
3940
cursorPosition: .outOfScope,
41+
cursorOffset: -1,
4042
selections: [],
4143
tabSize: 0,
4244
indentSize: 0,
@@ -128,6 +130,7 @@ struct PseudoCommandHandler {
128130
lines: [],
129131
uti: "",
130132
cursorPosition: .outOfScope,
133+
cursorOffset: -1,
131134
selections: [],
132135
tabSize: 0,
133136
indentSize: 0,
@@ -148,6 +151,7 @@ struct PseudoCommandHandler {
148151
lines: [],
149152
uti: "",
150153
cursorPosition: .outOfScope,
154+
cursorOffset: -1,
151155
selections: [],
152156
tabSize: 0,
153157
indentSize: 0,
@@ -206,7 +210,7 @@ struct PseudoCommandHandler {
206210
guard let focusElement = application.focusedElement,
207211
focusElement.description == "Source Editor"
208212
else { return }
209-
guard let (content, lines, _, cursorPosition) = await getFileContent(sourceEditor: nil)
213+
guard let (content, lines, _, cursorPosition, cursorOffset) = await getFileContent(sourceEditor: nil)
210214
else {
211215
PresentInWindowSuggestionPresenter()
212216
.presentErrorMessage("Unable to get file content.")
@@ -219,6 +223,7 @@ struct PseudoCommandHandler {
219223
lines: lines,
220224
uti: "",
221225
cursorPosition: cursorPosition,
226+
cursorOffset: cursorOffset,
222227
selections: [],
223228
tabSize: 0,
224229
indentSize: 0,
@@ -261,7 +266,7 @@ struct PseudoCommandHandler {
261266
guard let focusElement = application.focusedElement,
262267
focusElement.description == "Source Editor"
263268
else { return }
264-
guard let (content, lines, _, cursorPosition) = await getFileContent(sourceEditor: nil)
269+
guard let (content, lines, _, cursorPosition, cursorOffset) = await getFileContent(sourceEditor: nil)
265270
else {
266271
PresentInWindowSuggestionPresenter()
267272
.presentErrorMessage("Unable to get file content.")
@@ -274,6 +279,7 @@ struct PseudoCommandHandler {
274279
lines: lines,
275280
uti: "",
276281
cursorPosition: cursorPosition,
282+
cursorOffset: cursorOffset,
277283
selections: [],
278284
tabSize: 0,
279285
indentSize: 0,
@@ -361,7 +367,8 @@ extension PseudoCommandHandler {
361367
content: String,
362368
lines: [String],
363369
selections: [CursorRange],
364-
cursorPosition: CursorPosition
370+
cursorPosition: CursorPosition,
371+
cursorOffset: Int
365372
)?
366373
{
367374
guard let xcode = ActiveApplicationMonitor.shared.activeXcode
@@ -374,7 +381,7 @@ extension PseudoCommandHandler {
374381
let content = focusElement.value
375382
let split = content.breakLines(appendLineBreakToLastLine: false)
376383
let range = convertRangeToCursorRange(selectionRange, in: content)
377-
return (content, split, [range], range.start)
384+
return (content, split, [range], range.start, selectionRange.lowerBound)
378385
}
379386

380387
func getFileURL() async -> URL? {
@@ -410,6 +417,7 @@ extension PseudoCommandHandler {
410417
lines: content.lines,
411418
uti: uti,
412419
cursorPosition: content.cursorPosition,
420+
cursorOffset: content.cursorOffset,
413421
selections: content.selections.map {
414422
.init(start: $0.start, end: $0.end)
415423
},

EditorExtension/Helpers.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ extension EditorContent {
4747
uti: buffer.contentUTI,
4848
cursorPosition: ((buffer.selections.lastObject as? XCSourceTextRange)?.end).map {
4949
CursorPosition(line: $0.line, character: $0.column)
50-
} ?? CursorPosition(line: 0, character: 0),
50+
} ?? CursorPosition(line: 0, character: 0),
51+
cursorOffset: -1,
5152
selections: buffer.selections.map {
5253
let sl = ($0 as? XCSourceTextRange)?.start.line ?? 0
5354
let sc = ($0 as? XCSourceTextRange)?.start.column ?? 0

Pro

Submodule Pro updated from 4d30bd2 to ea5828c

Tool/Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ let package = Package(
1515
.library(name: "Logger", targets: ["Logger"]),
1616
.library(name: "OpenAIService", targets: ["OpenAIService"]),
1717
.library(name: "ChatTab", targets: ["ChatTab"]),
18+
.library(name: "FileSystem", targets: ["FileSystem"]),
1819
.library(
1920
name: "ChatContextCollector",
2021
targets: ["ChatContextCollector", "ActiveDocumentChatContextCollector"]
@@ -89,6 +90,8 @@ let package = Package(
8990

9091
.target(name: "Logger"),
9192

93+
.target(name: "FileSystem"),
94+
9295
.target(name: "ObjectiveCExceptionHandling"),
9396

9497
.target(
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
13+
/// A `ByteString` represents a sequence of bytes.
14+
///
15+
/// This struct provides useful operations for working with buffers of
16+
/// bytes. Conceptually it is just a contiguous array of bytes (UInt8), but it
17+
/// contains methods and default behavior suitable for common operations done
18+
/// using bytes strings.
19+
///
20+
/// This struct *is not* intended to be used for significant mutation of byte
21+
/// strings, we wish to retain the flexibility to micro-optimize the memory
22+
/// allocation of the storage (for example, by inlining the storage for small
23+
/// strings or and by eliminating wasted space in growable arrays). For
24+
/// construction of byte arrays, clients should use the `WritableByteStream` class
25+
/// and then convert to a `ByteString` when complete.
26+
public struct ByteString: ExpressibleByArrayLiteral, Hashable, Sendable {
27+
/// The buffer contents.
28+
@usableFromInline
29+
internal var _bytes: [UInt8]
30+
31+
/// Create an empty byte string.
32+
@inlinable
33+
public init() {
34+
_bytes = []
35+
}
36+
37+
/// Create a byte string from a byte array literal.
38+
@inlinable
39+
public init(arrayLiteral contents: UInt8...) {
40+
_bytes = contents
41+
}
42+
43+
/// Create a byte string from an array of bytes.
44+
@inlinable
45+
public init(_ contents: [UInt8]) {
46+
_bytes = contents
47+
}
48+
49+
/// Create a byte string from an array slice.
50+
@inlinable
51+
public init(_ contents: ArraySlice<UInt8>) {
52+
_bytes = Array(contents)
53+
}
54+
55+
/// Create a byte string from an byte buffer.
56+
@inlinable
57+
public init<S: Sequence> (_ contents: S) where S.Iterator.Element == UInt8 {
58+
_bytes = [UInt8](contents)
59+
}
60+
61+
/// Create a byte string from the UTF8 encoding of a string.
62+
@inlinable
63+
public init(encodingAsUTF8 string: String) {
64+
_bytes = [UInt8](string.utf8)
65+
}
66+
67+
/// Access the byte string contents as an array.
68+
@inlinable
69+
public var contents: [UInt8] {
70+
return _bytes
71+
}
72+
73+
/// Return the byte string size.
74+
@inlinable
75+
public var count: Int {
76+
return _bytes.count
77+
}
78+
79+
/// Gives a non-escaping closure temporary access to an immutable `Data` instance wrapping the `ByteString` without
80+
/// copying any memory around.
81+
///
82+
/// - Parameters:
83+
/// - closure: The closure that will have access to a `Data` instance for the duration of its lifetime.
84+
@inlinable
85+
public func withData<T>(_ closure: (Data) throws -> T) rethrows -> T {
86+
return try _bytes.withUnsafeBytes { pointer -> T in
87+
let mutatingPointer = UnsafeMutableRawPointer(mutating: pointer.baseAddress!)
88+
let data = Data(bytesNoCopy: mutatingPointer, count: pointer.count, deallocator: .none)
89+
return try closure(data)
90+
}
91+
}
92+
93+
/// Returns a `String` lowercase hexadecimal representation of the contents of the `ByteString`.
94+
@inlinable
95+
public var hexadecimalRepresentation: String {
96+
_bytes.reduce("") {
97+
var str = String($1, radix: 16)
98+
// The above method does not do zero padding.
99+
if str.count == 1 {
100+
str = "0" + str
101+
}
102+
return $0 + str
103+
}
104+
}
105+
}
106+
107+
/// Conform to CustomDebugStringConvertible.
108+
extension ByteString: CustomStringConvertible {
109+
/// Return the string decoded as a UTF8 sequence, or traps if not possible.
110+
public var description: String {
111+
return cString
112+
}
113+
114+
/// Return the string decoded as a UTF8 sequence, if possible.
115+
@inlinable
116+
public var validDescription: String? {
117+
// FIXME: This is very inefficient, we need a way to pass a buffer. It
118+
// is also wrong if the string contains embedded '\0' characters.
119+
let tmp = _bytes + [UInt8(0)]
120+
return tmp.withUnsafeBufferPointer { ptr in
121+
return String(validatingUTF8: unsafeBitCast(ptr.baseAddress, to: UnsafePointer<CChar>.self))
122+
}
123+
}
124+
125+
/// Return the string decoded as a UTF8 sequence, substituting replacement
126+
/// characters for ill-formed UTF8 sequences.
127+
@inlinable
128+
public var cString: String {
129+
return String(decoding: _bytes, as: Unicode.UTF8.self)
130+
}
131+
132+
@available(*, deprecated, message: "use description or validDescription instead")
133+
public var asString: String? {
134+
return validDescription
135+
}
136+
}
137+
138+
/// ByteStreamable conformance for a ByteString.
139+
extension ByteString: ByteStreamable {
140+
@inlinable
141+
public func write(to stream: WritableByteStream) {
142+
stream.write(_bytes)
143+
}
144+
}
145+
146+
/// StringLiteralConvertable conformance for a ByteString.
147+
extension ByteString: ExpressibleByStringLiteral {
148+
public typealias UnicodeScalarLiteralType = StringLiteralType
149+
public typealias ExtendedGraphemeClusterLiteralType = StringLiteralType
150+
151+
public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
152+
_bytes = [UInt8](value.utf8)
153+
}
154+
public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
155+
_bytes = [UInt8](value.utf8)
156+
}
157+
public init(stringLiteral value: StringLiteralType) {
158+
_bytes = [UInt8](value.utf8)
159+
}
160+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
13+
#if swift(<5.6)
14+
extension FileAttributeType: UnsafeSendable {}
15+
extension Date: UnsafeSendable {}
16+
#endif
17+
18+
/// File system information for a particular file.
19+
public struct FileInfo: Equatable, Codable, Sendable {
20+
21+
/// The device number.
22+
public let device: UInt64
23+
24+
/// The inode number.
25+
public let inode: UInt64
26+
27+
/// The size of the file.
28+
public let size: UInt64
29+
30+
/// The modification time of the file.
31+
public let modTime: Date
32+
33+
/// Kind of file system entity.
34+
public let posixPermissions: Int16
35+
36+
/// Kind of file system entity.
37+
public let fileType: FileAttributeType
38+
39+
public init(_ attrs: [FileAttributeKey : Any]) {
40+
let device = (attrs[.systemNumber] as? NSNumber)?.uint64Value
41+
assert(device != nil)
42+
self.device = device!
43+
44+
let inode = attrs[.systemFileNumber] as? UInt64
45+
assert(inode != nil)
46+
self.inode = inode!
47+
48+
let posixPermissions = (attrs[.posixPermissions] as? NSNumber)?.int16Value
49+
assert(posixPermissions != nil)
50+
self.posixPermissions = posixPermissions!
51+
52+
let fileType = attrs[.type] as? FileAttributeType
53+
assert(fileType != nil)
54+
self.fileType = fileType!
55+
56+
let size = attrs[.size] as? UInt64
57+
assert(size != nil)
58+
self.size = size!
59+
60+
let modTime = attrs[.modificationDate] as? Date
61+
assert(modTime != nil)
62+
self.modTime = modTime!
63+
}
64+
}
65+
66+
extension FileAttributeType: Codable {}

0 commit comments

Comments
 (0)