4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
6
import * as vscode from 'vscode' ;
7
+
7
8
import {
8
9
CompletionItem ,
9
10
CompletionList ,
10
11
CompletionParams ,
11
12
CompletionTriggerKind ,
13
+ InsertReplaceEdit ,
14
+ InsertTextMode ,
15
+ Position ,
12
16
RequestType ,
17
+ TextEdit ,
13
18
} from 'vscode-languageclient' ;
14
19
import { provideCompletionsCommand , resolveCompletionsCommand } from '../../../lsptoolshost/razorCommands' ;
15
20
import { RazorDocumentManager } from '../document/razorDocumentManager' ;
@@ -20,7 +25,7 @@ import { SerializableDelegatedCompletionParams } from './serializableDelegatedCo
20
25
import { SerializableDelegatedCompletionItemResolveParams } from './serializableDelegatedCompletionItemResolveParams' ;
21
26
import { LanguageKind } from '../rpc/languageKind' ;
22
27
import { UriConverter } from '../../../lsptoolshost/uriConverter' ;
23
- import { MarkupContent } from 'vscode-html-languageservice' ;
28
+ import { MarkupContent , Range } from 'vscode-html-languageservice' ;
24
29
25
30
export class CompletionHandler {
26
31
private static readonly completionEndpoint = 'razor/completion' ;
@@ -160,14 +165,21 @@ export class CompletionHandler {
160
165
for ( let i = 0 ; i < completionItems . length ; i ++ ) {
161
166
const completionItem = completionItems [ i ] ;
162
167
const convertedCompletionItem = < CompletionItem > {
168
+ command : completionItem . command , // no conversion needed as fields match
163
169
commitCharacters : completionItem . commitCharacters ,
164
170
detail : completionItem . detail ,
165
171
documentation : CompletionHandler . ToMarkupContent ( completionItem . documentation ) ,
166
172
filterText : completionItem . filterText ,
173
+ insertText : CompletionHandler . ToLspInsertText ( completionItem . insertText ) ,
174
+ insertTextMode : CompletionHandler . ToInsertTextMode ( completionItem . keepWhitespace ) ,
167
175
kind : completionItem . kind ,
168
- label : completionItem . label ,
176
+ label : CompletionHandler . ToLspCompletionItemLabel ( completionItem . label ) ,
169
177
preselect : completionItem . preselect ,
170
178
sortText : completionItem . sortText ,
179
+ textEdit : CompletionHandler . ToLspTextEdit (
180
+ CompletionHandler . ToLspInsertText ( completionItem . insertText ) ,
181
+ completionItem . range
182
+ ) ,
171
183
} ;
172
184
convertedCompletionItems [ i ] = convertedCompletionItem ;
173
185
}
@@ -250,4 +262,82 @@ export class CompletionHandler {
250
262
251
263
return markupContent ;
252
264
}
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
+ }
253
343
}
0 commit comments