44 *--------------------------------------------------------------------------------------------*/
55
66import * as vscode from 'vscode' ;
7+
78import {
89 CompletionItem ,
910 CompletionList ,
1011 CompletionParams ,
1112 CompletionTriggerKind ,
13+ InsertReplaceEdit ,
14+ InsertTextMode ,
15+ Position ,
1216 RequestType ,
17+ TextEdit ,
1318} from 'vscode-languageclient' ;
1419import { provideCompletionsCommand , resolveCompletionsCommand } from '../../../lsptoolshost/razorCommands' ;
1520import { RazorDocumentManager } from '../document/razorDocumentManager' ;
@@ -20,7 +25,7 @@ import { SerializableDelegatedCompletionParams } from './serializableDelegatedCo
2025import { SerializableDelegatedCompletionItemResolveParams } from './serializableDelegatedCompletionItemResolveParams' ;
2126import { LanguageKind } from '../rpc/languageKind' ;
2227import { UriConverter } from '../../../lsptoolshost/uriConverter' ;
23- import { MarkupContent } from 'vscode-html-languageservice' ;
28+ import { MarkupContent , Range } from 'vscode-html-languageservice' ;
2429
2530export class CompletionHandler {
2631 private static readonly completionEndpoint = 'razor/completion' ;
@@ -160,14 +165,21 @@ export class CompletionHandler {
160165 for ( let i = 0 ; i < completionItems . length ; i ++ ) {
161166 const completionItem = completionItems [ i ] ;
162167 const convertedCompletionItem = < CompletionItem > {
168+ command : completionItem . command , // no conversion needed as fields match
163169 commitCharacters : completionItem . commitCharacters ,
164170 detail : completionItem . detail ,
165171 documentation : CompletionHandler . ToMarkupContent ( completionItem . documentation ) ,
166172 filterText : completionItem . filterText ,
173+ insertText : CompletionHandler . ToLspInsertText ( completionItem . insertText ) ,
174+ insertTextMode : CompletionHandler . ToInsertTextMode ( completionItem . keepWhitespace ) ,
167175 kind : completionItem . kind ,
168- label : completionItem . label ,
176+ label : CompletionHandler . ToLspCompletionItemLabel ( completionItem . label ) ,
169177 preselect : completionItem . preselect ,
170178 sortText : completionItem . sortText ,
179+ textEdit : CompletionHandler . ToLspTextEdit (
180+ CompletionHandler . ToLspInsertText ( completionItem . insertText ) ,
181+ completionItem . range
182+ ) ,
171183 } ;
172184 convertedCompletionItems [ i ] = convertedCompletionItem ;
173185 }
@@ -250,4 +262,82 @@ export class CompletionHandler {
250262
251263 return markupContent ;
252264 }
265+
266+ private static ToLspCompletionItemLabel ( label : string | vscode . CompletionItemLabel ) : string {
267+ const completionItemLabel = label as vscode . CompletionItemLabel ;
268+ return completionItemLabel ?. label ?? < string > label ;
269+ }
270+
271+ private static ToLspInsertText ( insertText ?: string | vscode . SnippetString ) : string | undefined {
272+ const snippetString = insertText as vscode . SnippetString ;
273+ return snippetString ?. value ?? < string | undefined > insertText ;
274+ }
275+
276+ private static ToLspTextEdit (
277+ newText ?: string ,
278+ range ?: vscode . Range | { inserting : vscode . Range ; replacing : vscode . Range }
279+ ) : TextEdit | InsertReplaceEdit | undefined {
280+ if ( ! range ) {
281+ return undefined ;
282+ }
283+ if ( ! newText ) {
284+ newText = '' ;
285+ }
286+ const insertingRange = ( range as any ) . inserting ;
287+ if ( insertingRange ) {
288+ // do something
289+ }
290+ const replacingRange = ( range as any ) . replacing ;
291+ if ( replacingRange ) {
292+ // Do something else
293+ }
294+
295+ if ( ! ( insertingRange || replacingRange ) ) {
296+ const textEdit : TextEdit = {
297+ newText : newText ,
298+ range : this . ToLspRange ( < vscode . Range > range ) ,
299+ } ;
300+
301+ return textEdit ;
302+ }
303+
304+ if ( ! insertingRange || ! replacingRange ) {
305+ // We need both inserting and replacing ranges to convert to InsertReplaceEdit
306+ return undefined ;
307+ }
308+ const insertReplaceEdit : InsertReplaceEdit = {
309+ newText : newText ,
310+ insert : CompletionHandler . ToLspRange ( insertingRange ) ,
311+ replace : CompletionHandler . ToLspRange ( replacingRange ) ,
312+ } ;
313+
314+ return insertReplaceEdit ;
315+ }
316+
317+ private static ToLspRange ( range : vscode . Range ) : Range {
318+ const lspRange : Range = {
319+ start : CompletionHandler . ToLspPosition ( range . start ) ,
320+ end : CompletionHandler . ToLspPosition ( range . end ) ,
321+ } ;
322+
323+ return lspRange ;
324+ }
325+
326+ private static ToLspPosition ( position : vscode . Position ) : Position {
327+ const lspPosition : Position = {
328+ line : position . line ,
329+ character : position . character ,
330+ } ;
331+
332+ return lspPosition ;
333+ }
334+
335+ private static ToInsertTextMode ( keepWhitespace ?: boolean ) : InsertTextMode | undefined {
336+ if ( keepWhitespace === undefined ) {
337+ return undefined ;
338+ }
339+
340+ const insertTextMode : InsertTextMode = keepWhitespace ? InsertTextMode . asIs : InsertTextMode . adjustIndentation ;
341+ return insertTextMode ;
342+ }
253343}
0 commit comments