Skip to content

Commit 3935801

Browse files
committed
Merge tag 'fix-accept-suggestion' into develop
2 parents 17e9b5a + 7dc4607 commit 3935801

File tree

2 files changed

+71
-21
lines changed

2 files changed

+71
-21
lines changed

Core/Sources/SuggestionInjector/SuggestionInjector.swift

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,28 @@ public struct SuggestionInjector {
176176

177177
// appending suffix text not in range if needed.
178178
let skipAppendingDueToContinueTyping = {
179-
guard let first = toBeInserted.first?.dropLast(1), !first.isEmpty else { return false }
180-
let droppedLast = lastRemovedLine?.dropLast(1)
179+
guard let first = toBeInserted.first?
180+
.dropLast((toBeInserted.first?.hasSuffix("\n") ?? false) ? 1 : 0),
181+
!first.isEmpty else { return false }
182+
guard let last = toBeInserted.last?
183+
.dropLast((toBeInserted.last?.hasSuffix("\n") ?? false) ? 1 : 0),
184+
!last.isEmpty else { return false }
185+
let droppedLast = lastRemovedLine?
186+
.dropLast((lastRemovedLine?.hasSuffix("\n") ?? false) ? 1 : 0)
181187
guard let droppedLast, !droppedLast.isEmpty else { return false }
182188
// case 1: user keeps typing as the suggestion suggests.
183189
if first.hasPrefix(droppedLast) {
184190
return true
185191
}
186192
// case 2: user also typed the suffix of the suggestion (or auto-completed by Xcode)
187-
if end.character < droppedLast.count - 1 {
188-
let splitIndex = droppedLast.index(droppedLast.startIndex, offsetBy: end.character)
193+
if cursorPosition.character < droppedLast.count {
194+
let splitIndex = droppedLast.index(
195+
droppedLast.startIndex,
196+
offsetBy: cursorPosition.character
197+
)
189198
let prefix = droppedLast[..<splitIndex]
190199
let suffix = droppedLast[splitIndex...]
191-
if first.hasPrefix(prefix), first.hasSuffix(suffix) {
200+
if first.hasPrefix(prefix), last.hasSuffix(suffix) {
192201
return true
193202
}
194203
}

Core/Tests/SuggestionInjectorTests/AcceptSuggestionTests.swift

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ final class AcceptSuggestionTests: XCTestCase {
2626
)
2727
var extraInfo = SuggestionInjector.ExtraInfo()
2828
var lines = content.breakLines()
29-
var cursor = CursorPosition(line: 0, character: 0)
29+
var cursor = CursorPosition(line: 0, character: 1)
3030
SuggestionInjector().acceptSuggestion(
3131
intoContentWithoutSuggestion: &lines,
3232
cursorPosition: &cursor,
@@ -69,7 +69,7 @@ final class AcceptSuggestionTests: XCTestCase {
6969

7070
var extraInfo = SuggestionInjector.ExtraInfo()
7171
var lines = content.breakLines()
72-
var cursor = CursorPosition(line: 0, character: 0)
72+
var cursor = CursorPosition(line: 0, character: 12)
7373
SuggestionInjector().acceptSuggestion(
7474
intoContentWithoutSuggestion: &lines,
7575
cursorPosition: &cursor,
@@ -112,7 +112,7 @@ final class AcceptSuggestionTests: XCTestCase {
112112

113113
var extraInfo = SuggestionInjector.ExtraInfo()
114114
var lines = content.breakLines()
115-
var cursor = CursorPosition(line: 0, character: 0)
115+
var cursor = CursorPosition(line: 1, character: 12)
116116
SuggestionInjector().acceptSuggestion(
117117
intoContentWithoutSuggestion: &lines,
118118
cursorPosition: &cursor,
@@ -155,7 +155,7 @@ final class AcceptSuggestionTests: XCTestCase {
155155

156156
var extraInfo = SuggestionInjector.ExtraInfo()
157157
var lines = content.breakLines()
158-
var cursor = CursorPosition(line: 0, character: 0)
158+
var cursor = CursorPosition(line: 1, character: 12)
159159
SuggestionInjector().acceptSuggestion(
160160
intoContentWithoutSuggestion: &lines,
161161
cursorPosition: &cursor,
@@ -177,27 +177,66 @@ final class AcceptSuggestionTests: XCTestCase {
177177

178178
func test_accept_suggestion_overlap_continue_typing_has_suffix_typed() async throws {
179179
let content = """
180-
struct Cat {
181-
var n: String
182-
}
180+
print("")
183181
"""
184182
let text = """
183+
print("Hello World!")
184+
"""
185+
let suggestion = CodeSuggestion(
186+
text: text,
187+
position: .init(line: 0, character: 6),
188+
uuid: "",
189+
range: .init(
190+
start: .init(line: 0, character: 0),
191+
end: .init(line: 0, character: 6)
192+
),
193+
displayText: ""
194+
)
195+
196+
var extraInfo = SuggestionInjector.ExtraInfo()
197+
var lines = content.breakLines()
198+
var cursor = CursorPosition(line: 0, character: 7)
199+
SuggestionInjector().acceptSuggestion(
200+
intoContentWithoutSuggestion: &lines,
201+
cursorPosition: &cursor,
202+
completion: suggestion,
203+
extraInfo: &extraInfo
204+
)
205+
XCTAssertTrue(extraInfo.didChangeContent)
206+
XCTAssertTrue(extraInfo.didChangeCursorPosition)
207+
XCTAssertNil(extraInfo.suggestionRange)
208+
XCTAssertEqual(lines, content.breakLines().applying(extraInfo.modifications))
209+
XCTAssertEqual(cursor, .init(line: 0, character: 21))
210+
XCTAssertEqual(lines.joined(separator: ""), """
211+
print("Hello World!")
212+
213+
""")
214+
}
215+
216+
func test_accept_suggestion_overlap_continue_typing_has_suffix_typed_suggestion_has_multiple_lines() async throws {
217+
let content = """
218+
struct Cat {}
219+
"""
220+
let text = """
221+
struct Cat {
185222
var name: String
223+
var kind: String
224+
}
186225
"""
187226
let suggestion = CodeSuggestion(
188227
text: text,
189-
position: .init(line: 1, character: 9),
228+
position: .init(line: 0, character: 6),
190229
uuid: "",
191230
range: .init(
192-
start: .init(line: 1, character: 0),
193-
end: .init(line: 1, character: 9)
231+
start: .init(line: 0, character: 0),
232+
end: .init(line: 0, character: 6)
194233
),
195234
displayText: ""
196235
)
197236

198237
var extraInfo = SuggestionInjector.ExtraInfo()
199238
var lines = content.breakLines()
200-
var cursor = CursorPosition(line: 0, character: 0)
239+
var cursor = CursorPosition(line: 0, character: 12)
201240
SuggestionInjector().acceptSuggestion(
202241
intoContentWithoutSuggestion: &lines,
203242
cursorPosition: &cursor,
@@ -208,11 +247,13 @@ final class AcceptSuggestionTests: XCTestCase {
208247
XCTAssertTrue(extraInfo.didChangeCursorPosition)
209248
XCTAssertNil(extraInfo.suggestionRange)
210249
XCTAssertEqual(lines, content.breakLines().applying(extraInfo.modifications))
211-
XCTAssertEqual(cursor, .init(line: 1, character: 20))
250+
XCTAssertEqual(cursor, .init(line: 3, character: 1))
212251
XCTAssertEqual(lines.joined(separator: ""), """
213252
struct Cat {
214253
var name: String
254+
var kind: String
215255
}
256+
216257
""")
217258
}
218259

@@ -240,7 +281,7 @@ final class AcceptSuggestionTests: XCTestCase {
240281

241282
var extraInfo = SuggestionInjector.ExtraInfo()
242283
var lines = content.breakLines()
243-
var cursor = CursorPosition(line: 0, character: 0)
284+
var cursor = CursorPosition(line: 0, character: 18)
244285
SuggestionInjector().acceptSuggestion(
245286
intoContentWithoutSuggestion: &lines,
246287
cursorPosition: &cursor,
@@ -287,7 +328,7 @@ final class AcceptSuggestionTests: XCTestCase {
287328

288329
var extraInfo = SuggestionInjector.ExtraInfo()
289330
var lines = content.breakLines()
290-
var cursor = CursorPosition(line: 0, character: 0)
331+
var cursor = CursorPosition(line: 0, character: 18)
291332
SuggestionInjector().acceptSuggestion(
292333
intoContentWithoutSuggestion: &lines,
293334
cursorPosition: &cursor,
@@ -337,7 +378,7 @@ final class AcceptSuggestionTests: XCTestCase {
337378

338379
var extraInfo = SuggestionInjector.ExtraInfo()
339380
var lines = content.breakLines()
340-
var cursor = CursorPosition(line: 0, character: 0)
381+
var cursor = CursorPosition(line: 0, character: 7)
341382
SuggestionInjector().acceptSuggestion(
342383
intoContentWithoutSuggestion: &lines,
343384
cursorPosition: &cursor,
@@ -384,7 +425,7 @@ final class AcceptSuggestionTests: XCTestCase {
384425

385426
var extraInfo = SuggestionInjector.ExtraInfo()
386427
var lines = content.breakLines()
387-
var cursor = CursorPosition(line: 0, character: 0)
428+
var cursor = CursorPosition(line: 5, character: 34)
388429
SuggestionInjector().acceptSuggestion(
389430
intoContentWithoutSuggestion: &lines,
390431
cursorPosition: &cursor,

0 commit comments

Comments
 (0)