@@ -175,36 +175,52 @@ public struct SuggestionInjector {
175175 }
176176
177177 // appending suffix text not in range if needed.
178- let skipAppendingDueToContinueTyping = {
178+ let leftoverCount : Int = {
179+ let maxCount = lastRemovedLine? . count ?? 0
179180 guard let first = toBeInserted. first?
180181 . dropLast ( ( toBeInserted. first? . hasSuffix ( " \n " ) ?? false ) ? 1 : 0 ) ,
181- !first. isEmpty else { return false }
182+ !first. isEmpty else { return maxCount }
182183 guard let last = toBeInserted. last?
183184 . dropLast ( ( toBeInserted. last? . hasSuffix ( " \n " ) ?? false ) ? 1 : 0 ) ,
184- !last. isEmpty else { return false }
185+ !last. isEmpty else { return maxCount }
185186 let droppedLast = lastRemovedLine?
186187 . dropLast ( ( lastRemovedLine? . hasSuffix ( " \n " ) ?? false ) ? 1 : 0 )
187- guard let droppedLast, !droppedLast. isEmpty else { return false }
188+ guard let droppedLast, !droppedLast. isEmpty else { return maxCount }
188189 // case 1: user keeps typing as the suggestion suggests.
189190 if first. hasPrefix ( droppedLast) {
190- return true
191+ return 0
191192 }
192193 // case 2: user also typed the suffix of the suggestion (or auto-completed by Xcode)
193- if cursorPosition. character < droppedLast. count {
194- let splitIndex = droppedLast. index (
195- droppedLast. startIndex,
196- offsetBy: cursorPosition. character
197- )
198- let prefix = droppedLast [ ..< splitIndex]
199- let suffix = droppedLast [ splitIndex... ]
200- if first. hasPrefix ( prefix) , last. hasSuffix ( suffix) {
201- return true
194+ if end. character < droppedLast. count {
195+ // locate the split index, the prefix of which matches the suggestion prefix.
196+ var splitIndex : String . Index ? = nil
197+ for offset in end. character..< droppedLast. count {
198+ let proposedIndex = droppedLast. index (
199+ droppedLast. startIndex,
200+ offsetBy: offset
201+ )
202+ let prefix = droppedLast [ ..< proposedIndex]
203+ if first. hasPrefix ( prefix) {
204+ splitIndex = proposedIndex
205+ }
206+ }
207+
208+ // then check how many characters are not in the suffix of the suggestion.
209+ if let splitIndex {
210+ let suffix = droppedLast [ splitIndex... ]
211+ if last. hasSuffix ( suffix) {
212+ return 0
213+ }
214+ return suffix. count
202215 }
203216 }
204- return false
217+
218+ return maxCount
205219 } ( )
220+
221+ // appending suffix text not in range if needed.
206222 if let lastRemovedLine,
207- !skipAppendingDueToContinueTyping ,
223+ leftoverCount > 0 ,
208224 !lastRemovedLine. isEmptyOrNewLine,
209225 end. character >= 0 ,
210226 end. character - 1 < lastRemovedLine. count,
@@ -218,10 +234,9 @@ public struct SuggestionInjector {
218234 if toBeInserted [ toBeInserted. endIndex - 1 ] . hasSuffix ( " \n " ) {
219235 toBeInserted [ toBeInserted. endIndex - 1 ] . removeLast ( 1 )
220236 }
221- let leftover = lastRemovedLine [ leftoverRange]
237+ let leftover = lastRemovedLine [ leftoverRange] . suffix ( leftoverCount )
222238
223- toBeInserted [ toBeInserted. endIndex - 1 ]
224- . append ( contentsOf: leftover)
239+ toBeInserted [ toBeInserted. endIndex - 1 ] . append ( contentsOf: leftover)
225240 }
226241
227242 let cursorCol = toBeInserted [ toBeInserted. endIndex - 1 ] . count - 1
0 commit comments