@@ -1190,7 +1190,9 @@ export class Session {
1190
1190
return item ;
1191
1191
}
1192
1192
1193
- const { kind, kindModifiers, displayParts, documentation, tags} = details ;
1193
+ const { kind, kindModifiers, displayParts, documentation, tags, codeActions} = details ;
1194
+ const codeActionsDetail = generateCommandAndTextEditsFromCodeActions (
1195
+ codeActions ?? [ ] , filePath , ( path : string ) => this . projectService . getScriptInfo ( path ) ) ;
1194
1196
let desc = kindModifiers ? kindModifiers + ' ' : '' ;
1195
1197
if ( displayParts && displayParts . length > 0 ) {
1196
1198
// displayParts does not contain info about kindModifiers
@@ -1206,6 +1208,8 @@ export class Session {
1206
1208
documentation , tags , ( fileName ) => this . getLSAndScriptInfo ( fileName ) ?. scriptInfo )
1207
1209
. join ( '\n' ) ,
1208
1210
} ;
1211
+ item . additionalTextEdits = codeActionsDetail . additionalTextEdits ;
1212
+ item . command = codeActionsDetail . command ;
1209
1213
return item ;
1210
1214
}
1211
1215
@@ -1340,3 +1344,67 @@ function getCodeFixesAll(
1340
1344
}
1341
1345
return lspCodeActions ;
1342
1346
}
1347
+
1348
+ /**
1349
+ * In the completion item, the `additionalTextEdits` can only be included the changes about the
1350
+ * current file, the other changes should be inserted by the vscode command.
1351
+ *
1352
+ * For example, when the user selects a component in an HTML file, the extension inserts the
1353
+ * selector in the HTML file and auto-generates the import declaration in the TS file.
1354
+ *
1355
+ * The code is copied from
1356
+ * [here](https://github.com/microsoft/vscode/blob/4608b378a8101ff273fa5db36516da6022f66bbf/extensions/typescript-language-features/src/languageFeatures/completions.ts#L304)
1357
+ */
1358
+ function generateCommandAndTextEditsFromCodeActions (
1359
+ codeActions : ts . CodeAction [ ] , currentFilePath : string ,
1360
+ getScriptInfo : ( path : string ) => ts . server . ScriptInfo |
1361
+ undefined ) : { command ?: lsp . Command ; additionalTextEdits ?: lsp . TextEdit [ ] } {
1362
+ if ( codeActions . length === 0 ) {
1363
+ return { } ;
1364
+ }
1365
+
1366
+ // Try to extract out the additionalTextEdits for the current file.
1367
+ // Also check if we still have to apply other workspace edits and commands
1368
+ // using a vscode command
1369
+ const additionalTextEdits : lsp . TextEdit [ ] = [ ] ;
1370
+ const commandTextEditors : lsp . WorkspaceEdit [ ] = [ ] ;
1371
+
1372
+ for ( const tsAction of codeActions ) {
1373
+ const currentFileChanges =
1374
+ tsAction . changes . filter ( change => change . fileName === currentFilePath ) ;
1375
+ const otherWorkspaceFileChanges =
1376
+ tsAction . changes . filter ( change => change . fileName !== currentFilePath ) ;
1377
+
1378
+ if ( currentFileChanges . length > 0 ) {
1379
+ // Apply all edits in the current file using `additionalTextEdits`
1380
+ const additionalWorkspaceEdit =
1381
+ tsFileTextChangesToLspWorkspaceEdit ( currentFileChanges , getScriptInfo ) . changes ;
1382
+ if ( additionalWorkspaceEdit !== undefined ) {
1383
+ for ( const edit of Object . values ( additionalWorkspaceEdit ) ) {
1384
+ additionalTextEdits . push ( ...edit ) ;
1385
+ }
1386
+ }
1387
+ }
1388
+
1389
+ if ( otherWorkspaceFileChanges . length > 0 ) {
1390
+ commandTextEditors . push (
1391
+ tsFileTextChangesToLspWorkspaceEdit ( otherWorkspaceFileChanges , getScriptInfo ) ,
1392
+ ) ;
1393
+ }
1394
+ }
1395
+
1396
+ let command : lsp . Command | undefined = undefined ;
1397
+ if ( commandTextEditors . length > 0 ) {
1398
+ // Create command that applies all edits not in the current file.
1399
+ command = {
1400
+ title : '' ,
1401
+ command : 'angular.applyCompletionCodeAction' ,
1402
+ arguments : [ commandTextEditors ] ,
1403
+ } ;
1404
+ }
1405
+
1406
+ return {
1407
+ command,
1408
+ additionalTextEdits : additionalTextEdits . length ? additionalTextEdits : undefined
1409
+ } ;
1410
+ }
0 commit comments