@@ -39,6 +39,7 @@ interface CompletionContext {
3939
4040 readonly wordRange : vscode . Range | undefined ;
4141 readonly line : string ;
42+ readonly optionalReplacementRange : vscode . Range | undefined ;
4243}
4344
4445type ResolvedCompletionItem = {
@@ -363,18 +364,25 @@ class MyCompletionItem extends vscode.CompletionItem {
363364
364365 private getRangeFromReplacementSpan ( tsEntry : Proto . CompletionEntry , completionContext : CompletionContext ) {
365366 if ( ! tsEntry . replacementSpan ) {
366- return ;
367+ if ( completionContext . optionalReplacementRange ) {
368+ return {
369+ inserting : new vscode . Range ( completionContext . optionalReplacementRange . start , this . position ) ,
370+ replacing : completionContext . optionalReplacementRange ,
371+ } ;
372+ }
373+
374+ return undefined ;
367375 }
368376
369- let replaceRange = typeConverters . Range . fromTextSpan ( tsEntry . replacementSpan ) ;
377+ // If TS returns an explicit replacement range on this item, we should use it for both types of completion
378+
370379 // Make sure we only replace a single line at most
380+ let replaceRange = typeConverters . Range . fromTextSpan ( tsEntry . replacementSpan ) ;
371381 if ( ! replaceRange . isSingleLine ) {
372382 replaceRange = new vscode . Range ( replaceRange . start . line , replaceRange . start . character , replaceRange . start . line , completionContext . line . length ) ;
373383 }
374-
375- // If TS returns an explicit replacement range, we should use it for both types of completion
376384 return {
377- inserting : new vscode . Range ( replaceRange . start , this . position ) ,
385+ inserting : replaceRange ,
378386 replacing : replaceRange ,
379387 } ;
380388 }
@@ -735,6 +743,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider<
735743 let metadata : any | undefined ;
736744 let response : ServerResponse . Response < Proto . CompletionInfoResponse > | undefined ;
737745 let duration : number | undefined ;
746+ let optionalReplacementRange : vscode . Range | undefined ;
738747 if ( this . client . apiVersion . gte ( API . v300 ) ) {
739748 const startTime = Date . now ( ) ;
740749 try {
@@ -762,9 +771,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider<
762771 metadata = response . metadata ;
763772
764773 if ( response . body . optionalReplacementSpan ) {
765- for ( const entry of entries ) {
766- entry . replacementSpan ??= response . body . optionalReplacementSpan ;
767- }
774+ optionalReplacementRange = typeConverters . Range . fromTextSpan ( response . body . optionalReplacementSpan ) ;
768775 }
769776 } else {
770777 const response = await this . client . interruptGetErr ( ( ) => this . client . execute ( 'completions' , args , token ) ) ;
@@ -784,6 +791,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider<
784791 wordRange,
785792 line : line . text ,
786793 completeFunctionCalls : completionConfiguration . completeFunctionCalls ,
794+ optionalReplacementRange,
787795 } ;
788796
789797 let includesPackageJsonImport = false ;
0 commit comments