@lvce-editor/completion-worker 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/completionWorkerMain.js +494 -167
- package/package.json +1 -1
|
@@ -1046,8 +1046,30 @@ const create$1 = (uid, x, y, width, height, editorUid, editorLanguageId) => {
|
|
|
1046
1046
|
set$2(uid, state, state);
|
|
1047
1047
|
};
|
|
1048
1048
|
|
|
1049
|
-
const
|
|
1050
|
-
|
|
1049
|
+
const isEqual$3 = (oldState, newState) => {
|
|
1050
|
+
return oldState.x === newState.x && oldState.y === newState.y && oldState.width === newState.width && oldState.height === newState.height;
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
const isEqual$2 = (oldState, newState) => {
|
|
1054
|
+
return oldState.version === newState.version;
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
const isEqual$1 = (oldState, newState) => {
|
|
1058
|
+
return oldState.items === newState.items;
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
const isEqual = (oldState, newState) => {
|
|
1062
|
+
return oldState.version === newState.version;
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
const RenderItems = 1;
|
|
1066
|
+
const RenderBounds = 8;
|
|
1067
|
+
const RenderEventListeners = 11;
|
|
1068
|
+
const RenderUid = 12;
|
|
1069
|
+
const RenderContent = 13;
|
|
1070
|
+
|
|
1071
|
+
const modules = [isEqual$2, isEqual$1, isEqual$3, isEqual];
|
|
1072
|
+
const numbers = [RenderEventListeners, RenderItems, RenderBounds, RenderUid];
|
|
1051
1073
|
|
|
1052
1074
|
const diff = (oldState, newState) => {
|
|
1053
1075
|
const diffResult = [];
|
|
@@ -1075,159 +1097,6 @@ const getCommandIds = () => {
|
|
|
1075
1097
|
return commandIds;
|
|
1076
1098
|
};
|
|
1077
1099
|
|
|
1078
|
-
const getPortTuple = () => {
|
|
1079
|
-
const {
|
|
1080
|
-
port1,
|
|
1081
|
-
port2
|
|
1082
|
-
} = new MessageChannel();
|
|
1083
|
-
return {
|
|
1084
|
-
port1,
|
|
1085
|
-
port2
|
|
1086
|
-
};
|
|
1087
|
-
};
|
|
1088
|
-
|
|
1089
|
-
const rpcs = Object.create(null);
|
|
1090
|
-
const set$9 = (id, rpc) => {
|
|
1091
|
-
rpcs[id] = rpc;
|
|
1092
|
-
};
|
|
1093
|
-
const get = id => {
|
|
1094
|
-
return rpcs[id];
|
|
1095
|
-
};
|
|
1096
|
-
|
|
1097
|
-
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
1098
|
-
|
|
1099
|
-
const create = rpcId => {
|
|
1100
|
-
return {
|
|
1101
|
-
// @ts-ignore
|
|
1102
|
-
invoke(method, ...params) {
|
|
1103
|
-
const rpc = get(rpcId);
|
|
1104
|
-
// @ts-ignore
|
|
1105
|
-
return rpc.invoke(method, ...params);
|
|
1106
|
-
},
|
|
1107
|
-
// @ts-ignore
|
|
1108
|
-
invokeAndTransfer(method, ...params) {
|
|
1109
|
-
const rpc = get(rpcId);
|
|
1110
|
-
// @ts-ignore
|
|
1111
|
-
return rpc.invokeAndTransfer(method, ...params);
|
|
1112
|
-
},
|
|
1113
|
-
set(rpc) {
|
|
1114
|
-
set$9(rpcId, rpc);
|
|
1115
|
-
}
|
|
1116
|
-
};
|
|
1117
|
-
};
|
|
1118
|
-
const EditorWorker$1 = 99;
|
|
1119
|
-
const ExtensionHostWorker = 44;
|
|
1120
|
-
const {
|
|
1121
|
-
invoke: invoke$8,
|
|
1122
|
-
invokeAndTransfer: invokeAndTransfer$8,
|
|
1123
|
-
set: set$8
|
|
1124
|
-
} = create(EditorWorker$1);
|
|
1125
|
-
const EditorWorker = {
|
|
1126
|
-
__proto__: null,
|
|
1127
|
-
invoke: invoke$8,
|
|
1128
|
-
invokeAndTransfer: invokeAndTransfer$8,
|
|
1129
|
-
set: set$8
|
|
1130
|
-
};
|
|
1131
|
-
const {
|
|
1132
|
-
invoke: invoke$6,
|
|
1133
|
-
set: set$6
|
|
1134
|
-
} = create(ExtensionHostWorker);
|
|
1135
|
-
const ExtensionHost = {
|
|
1136
|
-
__proto__: null,
|
|
1137
|
-
invoke: invoke$6,
|
|
1138
|
-
set: set$6
|
|
1139
|
-
};
|
|
1140
|
-
|
|
1141
|
-
const {
|
|
1142
|
-
invoke: invoke$1,
|
|
1143
|
-
set: set$1,
|
|
1144
|
-
invokeAndTransfer
|
|
1145
|
-
} = EditorWorker;
|
|
1146
|
-
|
|
1147
|
-
const sendMessagePortToExtensionHostWorker = async port => {
|
|
1148
|
-
const command = 'HandleMessagePort.handleMessagePort2';
|
|
1149
|
-
// @ts-ignore
|
|
1150
|
-
await invokeAndTransfer(
|
|
1151
|
-
// @ts-ignore
|
|
1152
|
-
'SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, 0 // TODO
|
|
1153
|
-
);
|
|
1154
|
-
};
|
|
1155
|
-
|
|
1156
|
-
const createExtensionHostRpc = async () => {
|
|
1157
|
-
try {
|
|
1158
|
-
const {
|
|
1159
|
-
port1,
|
|
1160
|
-
port2
|
|
1161
|
-
} = getPortTuple();
|
|
1162
|
-
await sendMessagePortToExtensionHostWorker(port2);
|
|
1163
|
-
const rpc = await PlainMessagePortRpcParent.create({
|
|
1164
|
-
commandMap: {},
|
|
1165
|
-
messagePort: port1
|
|
1166
|
-
});
|
|
1167
|
-
return rpc;
|
|
1168
|
-
} catch (error) {
|
|
1169
|
-
throw new VError(error, `Failed to create extension host rpc`);
|
|
1170
|
-
}
|
|
1171
|
-
};
|
|
1172
|
-
|
|
1173
|
-
const {
|
|
1174
|
-
invoke,
|
|
1175
|
-
set
|
|
1176
|
-
} = ExtensionHost;
|
|
1177
|
-
|
|
1178
|
-
const initialize = async () => {
|
|
1179
|
-
const rpc = await createExtensionHostRpc();
|
|
1180
|
-
set(rpc);
|
|
1181
|
-
};
|
|
1182
|
-
|
|
1183
|
-
const OnCompletion = 'onCompletion';
|
|
1184
|
-
|
|
1185
|
-
const CompletionExecute = 'ExtensionHostCompletion.execute';
|
|
1186
|
-
|
|
1187
|
-
// TODO add tests for this
|
|
1188
|
-
const activateByEvent = async event => {
|
|
1189
|
-
// @ts-ignore
|
|
1190
|
-
await invoke$1('ActivateByEvent.activateByEvent', event);
|
|
1191
|
-
};
|
|
1192
|
-
|
|
1193
|
-
const execute = async ({
|
|
1194
|
-
editorLanguageId,
|
|
1195
|
-
editorUid,
|
|
1196
|
-
args,
|
|
1197
|
-
event,
|
|
1198
|
-
method,
|
|
1199
|
-
noProviderFoundMessage,
|
|
1200
|
-
noProviderFoundResult = undefined
|
|
1201
|
-
}) => {
|
|
1202
|
-
const fullEvent = `${event}:${editorLanguageId}`;
|
|
1203
|
-
await activateByEvent(fullEvent);
|
|
1204
|
-
const result = await invoke(method, editorUid, ...args);
|
|
1205
|
-
return result;
|
|
1206
|
-
};
|
|
1207
|
-
|
|
1208
|
-
const executeCompletionProvider = async (editorUid, editorLanguageId, offset) => {
|
|
1209
|
-
return execute({
|
|
1210
|
-
editorUid,
|
|
1211
|
-
editorLanguageId,
|
|
1212
|
-
event: OnCompletion,
|
|
1213
|
-
method: CompletionExecute,
|
|
1214
|
-
args: [offset],
|
|
1215
|
-
noProviderFoundMessage: 'no completion provider found',
|
|
1216
|
-
noProviderFoundResult: []});
|
|
1217
|
-
};
|
|
1218
|
-
|
|
1219
|
-
const getOffsetAtCursor = editorUid => {
|
|
1220
|
-
// TODO ask editor worker
|
|
1221
|
-
return 0;
|
|
1222
|
-
};
|
|
1223
|
-
|
|
1224
|
-
// TODO possible to do this with events/state machine instead of promises -> enables canceling operations / concurrent calls
|
|
1225
|
-
const getCompletions = async (editorUid, editorLanguageId) => {
|
|
1226
|
-
const offset = getOffsetAtCursor();
|
|
1227
|
-
const completions = await executeCompletionProvider(editorUid, editorLanguageId, offset);
|
|
1228
|
-
return completions;
|
|
1229
|
-
};
|
|
1230
|
-
|
|
1231
1100
|
const Diagonal = 1;
|
|
1232
1101
|
const Left = 2;
|
|
1233
1102
|
|
|
@@ -1424,12 +1293,6 @@ const filterCompletionItems = (completionItems, word) => {
|
|
|
1424
1293
|
return filteredCompletions;
|
|
1425
1294
|
};
|
|
1426
1295
|
|
|
1427
|
-
const getFinalDeltaY = (height, itemHeight, itemsLength) => {
|
|
1428
|
-
const contentHeight = itemsLength * itemHeight;
|
|
1429
|
-
const finalDeltaY = Math.max(contentHeight - height, 0);
|
|
1430
|
-
return finalDeltaY;
|
|
1431
|
-
};
|
|
1432
|
-
|
|
1433
1296
|
const getListHeight = (itemsLength, itemHeight, maxHeight) => {
|
|
1434
1297
|
number(itemsLength);
|
|
1435
1298
|
number(itemHeight);
|
|
@@ -1441,14 +1304,210 @@ const getListHeight = (itemsLength, itemHeight, maxHeight) => {
|
|
|
1441
1304
|
return Math.min(totalHeight, maxHeight);
|
|
1442
1305
|
};
|
|
1443
1306
|
|
|
1307
|
+
const rpcs = Object.create(null);
|
|
1308
|
+
const set$a = (id, rpc) => {
|
|
1309
|
+
rpcs[id] = rpc;
|
|
1310
|
+
};
|
|
1311
|
+
const get = id => {
|
|
1312
|
+
return rpcs[id];
|
|
1313
|
+
};
|
|
1314
|
+
|
|
1315
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
1316
|
+
|
|
1317
|
+
const create = rpcId => {
|
|
1318
|
+
return {
|
|
1319
|
+
// @ts-ignore
|
|
1320
|
+
invoke(method, ...params) {
|
|
1321
|
+
const rpc = get(rpcId);
|
|
1322
|
+
// @ts-ignore
|
|
1323
|
+
return rpc.invoke(method, ...params);
|
|
1324
|
+
},
|
|
1325
|
+
// @ts-ignore
|
|
1326
|
+
invokeAndTransfer(method, ...params) {
|
|
1327
|
+
const rpc = get(rpcId);
|
|
1328
|
+
// @ts-ignore
|
|
1329
|
+
return rpc.invokeAndTransfer(method, ...params);
|
|
1330
|
+
},
|
|
1331
|
+
set(rpc) {
|
|
1332
|
+
set$a(rpcId, rpc);
|
|
1333
|
+
}
|
|
1334
|
+
};
|
|
1335
|
+
};
|
|
1336
|
+
const EditorWorker$1 = 99;
|
|
1337
|
+
const ExtensionHostWorker = 44;
|
|
1338
|
+
const {
|
|
1339
|
+
invoke: invoke$9,
|
|
1340
|
+
invokeAndTransfer: invokeAndTransfer$9,
|
|
1341
|
+
set: set$9
|
|
1342
|
+
} = create(EditorWorker$1);
|
|
1343
|
+
const EditorWorker = {
|
|
1344
|
+
__proto__: null,
|
|
1345
|
+
invoke: invoke$9,
|
|
1346
|
+
invokeAndTransfer: invokeAndTransfer$9,
|
|
1347
|
+
set: set$9
|
|
1348
|
+
};
|
|
1349
|
+
const {
|
|
1350
|
+
invoke: invoke$7,
|
|
1351
|
+
set: set$7
|
|
1352
|
+
} = create(ExtensionHostWorker);
|
|
1353
|
+
const ExtensionHost = {
|
|
1354
|
+
__proto__: null,
|
|
1355
|
+
invoke: invoke$7,
|
|
1356
|
+
set: set$7
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1359
|
+
const {
|
|
1360
|
+
invoke: invoke$1,
|
|
1361
|
+
set: set$1,
|
|
1362
|
+
invokeAndTransfer
|
|
1363
|
+
} = EditorWorker;
|
|
1364
|
+
|
|
1444
1365
|
const getPositionAtCursor = async parentUid => {
|
|
1445
1366
|
const position = await invoke$1('Editor.getPositionAtCursor', parentUid);
|
|
1446
1367
|
return position;
|
|
1447
1368
|
};
|
|
1448
1369
|
|
|
1449
|
-
const
|
|
1370
|
+
const getWordBefore = async (editorUid, rowIndex, columnIndex) => {
|
|
1371
|
+
// @ts-ignore
|
|
1372
|
+
return invoke$1('Editor.getWordBefore2', editorUid, rowIndex, columnIndex);
|
|
1373
|
+
};
|
|
1374
|
+
|
|
1375
|
+
const handleEditorType = async state => {
|
|
1376
|
+
const {
|
|
1377
|
+
unfilteredItems,
|
|
1378
|
+
itemHeight,
|
|
1379
|
+
maxHeight,
|
|
1380
|
+
editorUid
|
|
1381
|
+
} = state;
|
|
1382
|
+
const {
|
|
1383
|
+
x,
|
|
1384
|
+
y,
|
|
1385
|
+
rowIndex,
|
|
1386
|
+
columnIndex
|
|
1387
|
+
} = await getPositionAtCursor(editorUid);
|
|
1388
|
+
const wordAtOffset = await getWordBefore(editorUid, rowIndex, columnIndex);
|
|
1389
|
+
const items = filterCompletionItems(unfilteredItems, wordAtOffset);
|
|
1390
|
+
const newMinLineY = 0;
|
|
1391
|
+
const newMaxLineY = Math.min(items.length, 8);
|
|
1392
|
+
const height = getListHeight(items.length, itemHeight, maxHeight);
|
|
1393
|
+
const finalDeltaY = items.length * itemHeight - height;
|
|
1394
|
+
return {
|
|
1395
|
+
...state,
|
|
1396
|
+
items,
|
|
1397
|
+
x,
|
|
1398
|
+
y,
|
|
1399
|
+
minLineY: newMinLineY,
|
|
1400
|
+
maxLineY: newMaxLineY,
|
|
1401
|
+
leadingWord: wordAtOffset,
|
|
1402
|
+
height,
|
|
1403
|
+
finalDeltaY
|
|
1404
|
+
};
|
|
1405
|
+
};
|
|
1406
|
+
|
|
1407
|
+
const getPortTuple = () => {
|
|
1408
|
+
const {
|
|
1409
|
+
port1,
|
|
1410
|
+
port2
|
|
1411
|
+
} = new MessageChannel();
|
|
1412
|
+
return {
|
|
1413
|
+
port1,
|
|
1414
|
+
port2
|
|
1415
|
+
};
|
|
1416
|
+
};
|
|
1417
|
+
|
|
1418
|
+
const sendMessagePortToExtensionHostWorker = async port => {
|
|
1419
|
+
const command = 'HandleMessagePort.handleMessagePort2';
|
|
1420
|
+
// @ts-ignore
|
|
1421
|
+
await invokeAndTransfer(
|
|
1422
|
+
// @ts-ignore
|
|
1423
|
+
'SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, 0 // TODO
|
|
1424
|
+
);
|
|
1425
|
+
};
|
|
1426
|
+
|
|
1427
|
+
const createExtensionHostRpc = async () => {
|
|
1428
|
+
try {
|
|
1429
|
+
const {
|
|
1430
|
+
port1,
|
|
1431
|
+
port2
|
|
1432
|
+
} = getPortTuple();
|
|
1433
|
+
await sendMessagePortToExtensionHostWorker(port2);
|
|
1434
|
+
const rpc = await PlainMessagePortRpcParent.create({
|
|
1435
|
+
commandMap: {},
|
|
1436
|
+
messagePort: port1
|
|
1437
|
+
});
|
|
1438
|
+
return rpc;
|
|
1439
|
+
} catch (error) {
|
|
1440
|
+
throw new VError(error, `Failed to create extension host rpc`);
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1444
|
+
const {
|
|
1445
|
+
invoke,
|
|
1446
|
+
set
|
|
1447
|
+
} = ExtensionHost;
|
|
1448
|
+
|
|
1449
|
+
const initialize = async () => {
|
|
1450
|
+
const rpc = await createExtensionHostRpc();
|
|
1451
|
+
set(rpc);
|
|
1452
|
+
};
|
|
1453
|
+
|
|
1454
|
+
const OnCompletion = 'onCompletion';
|
|
1455
|
+
|
|
1456
|
+
const CompletionExecute = 'ExtensionHostCompletion.execute';
|
|
1457
|
+
|
|
1458
|
+
// TODO add tests for this
|
|
1459
|
+
const activateByEvent = async event => {
|
|
1460
|
+
// @ts-ignore
|
|
1461
|
+
await invoke$1('ActivateByEvent.activateByEvent', event);
|
|
1462
|
+
};
|
|
1463
|
+
|
|
1464
|
+
const execute = async ({
|
|
1465
|
+
editorLanguageId,
|
|
1466
|
+
editorUid,
|
|
1467
|
+
args,
|
|
1468
|
+
event,
|
|
1469
|
+
method,
|
|
1470
|
+
noProviderFoundMessage,
|
|
1471
|
+
noProviderFoundResult = undefined
|
|
1472
|
+
}) => {
|
|
1473
|
+
const fullEvent = `${event}:${editorLanguageId}`;
|
|
1474
|
+
await activateByEvent(fullEvent);
|
|
1475
|
+
const result = await invoke(method, editorUid, ...args);
|
|
1476
|
+
return result;
|
|
1477
|
+
};
|
|
1478
|
+
|
|
1479
|
+
const executeCompletionProvider = async (editorUid, editorLanguageId, offset) => {
|
|
1480
|
+
return execute({
|
|
1481
|
+
editorUid,
|
|
1482
|
+
editorLanguageId,
|
|
1483
|
+
event: OnCompletion,
|
|
1484
|
+
method: CompletionExecute,
|
|
1485
|
+
args: [offset],
|
|
1486
|
+
noProviderFoundMessage: 'no completion provider found',
|
|
1487
|
+
noProviderFoundResult: []});
|
|
1488
|
+
};
|
|
1489
|
+
|
|
1490
|
+
const getOffsetAtCursor = editorUid => {
|
|
1450
1491
|
// TODO ask editor worker
|
|
1451
|
-
return
|
|
1492
|
+
return 0;
|
|
1493
|
+
};
|
|
1494
|
+
|
|
1495
|
+
// TODO possible to do this with events/state machine instead of promises -> enables canceling operations / concurrent calls
|
|
1496
|
+
const getCompletions = async (editorUid, editorLanguageId) => {
|
|
1497
|
+
const offset = getOffsetAtCursor();
|
|
1498
|
+
const completions = await executeCompletionProvider(editorUid, editorLanguageId, offset);
|
|
1499
|
+
return completions;
|
|
1500
|
+
};
|
|
1501
|
+
|
|
1502
|
+
const getFinalDeltaY = (height, itemHeight, itemsLength) => {
|
|
1503
|
+
const contentHeight = itemsLength * itemHeight;
|
|
1504
|
+
const finalDeltaY = Math.max(contentHeight - height, 0);
|
|
1505
|
+
return finalDeltaY;
|
|
1506
|
+
};
|
|
1507
|
+
|
|
1508
|
+
const getWordAtOffset = async editorUid => {
|
|
1509
|
+
// @ts-ignore
|
|
1510
|
+
return invoke$1('Editor.getWordAtOffset2', editorUid);
|
|
1452
1511
|
};
|
|
1453
1512
|
|
|
1454
1513
|
const loadContent = async state => {
|
|
@@ -1459,7 +1518,7 @@ const loadContent = async state => {
|
|
|
1459
1518
|
editorLanguageId
|
|
1460
1519
|
} = state;
|
|
1461
1520
|
const unfilteredItems = await getCompletions(editorUid, editorLanguageId);
|
|
1462
|
-
const wordAtOffset = await getWordAtOffset();
|
|
1521
|
+
const wordAtOffset = await getWordAtOffset(editorUid);
|
|
1463
1522
|
const items = filterCompletionItems(unfilteredItems, wordAtOffset);
|
|
1464
1523
|
const {
|
|
1465
1524
|
rowIndex,
|
|
@@ -1491,9 +1550,20 @@ const loadContent = async state => {
|
|
|
1491
1550
|
};
|
|
1492
1551
|
};
|
|
1493
1552
|
|
|
1494
|
-
const
|
|
1495
|
-
|
|
1553
|
+
const SetBounds = 'Viewlet.setBounds';
|
|
1496
1554
|
const SetDom2 = 'Viewlet.setDom2';
|
|
1555
|
+
const SetEventListeners = 'Viewlet.registerEventListeners';
|
|
1556
|
+
|
|
1557
|
+
const renderBounds = (oldState, newState) => {
|
|
1558
|
+
const {
|
|
1559
|
+
x,
|
|
1560
|
+
y,
|
|
1561
|
+
width,
|
|
1562
|
+
height,
|
|
1563
|
+
uid
|
|
1564
|
+
} = newState;
|
|
1565
|
+
return [SetBounds, uid, x, y, width, height];
|
|
1566
|
+
};
|
|
1497
1567
|
|
|
1498
1568
|
const renderContent = (oldState, newState) => {
|
|
1499
1569
|
const {
|
|
@@ -1503,10 +1573,266 @@ const renderContent = (oldState, newState) => {
|
|
|
1503
1573
|
return [SetDom2, uid, dom];
|
|
1504
1574
|
};
|
|
1505
1575
|
|
|
1576
|
+
const getEventListeners = uid => {
|
|
1577
|
+
return [];
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
const renderEventListeners = state => {
|
|
1581
|
+
const {
|
|
1582
|
+
uid
|
|
1583
|
+
} = state;
|
|
1584
|
+
const eventListeners = getEventListeners();
|
|
1585
|
+
return [SetEventListeners, uid, eventListeners];
|
|
1586
|
+
};
|
|
1587
|
+
|
|
1588
|
+
const emptyObject = {};
|
|
1589
|
+
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
1590
|
+
const i18nString = (key, placeholders = emptyObject) => {
|
|
1591
|
+
if (placeholders === emptyObject) {
|
|
1592
|
+
return key;
|
|
1593
|
+
}
|
|
1594
|
+
const replacer = (match, rest) => {
|
|
1595
|
+
return placeholders[rest];
|
|
1596
|
+
};
|
|
1597
|
+
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
1598
|
+
};
|
|
1599
|
+
|
|
1600
|
+
const NoResults = 'No Results';
|
|
1601
|
+
|
|
1602
|
+
const noResults = () => {
|
|
1603
|
+
return i18nString(NoResults);
|
|
1604
|
+
};
|
|
1605
|
+
|
|
1606
|
+
const None = 'none';
|
|
1607
|
+
const Option = 'option';
|
|
1608
|
+
|
|
1609
|
+
const ColoredMaskIcon = 'ColoredMaskIcon';
|
|
1610
|
+
const EditorCompletionItem = 'EditorCompletionItem';
|
|
1611
|
+
const EditorCompletionItemDeprecated = 'EditorCompletionItemDeprecated';
|
|
1612
|
+
const EditorCompletionItemFocused = 'EditorCompletionItemFocused';
|
|
1613
|
+
const EditorCompletionItemHighlight = 'EditorCompletionItemHighlight';
|
|
1614
|
+
const FileIcon = 'FileIcon';
|
|
1615
|
+
const Label = 'Label';
|
|
1616
|
+
|
|
1617
|
+
const Div = 4;
|
|
1618
|
+
const Span = 8;
|
|
1619
|
+
const Img = 17;
|
|
1620
|
+
|
|
1621
|
+
const getFileIconVirtualDom = icon => {
|
|
1622
|
+
return {
|
|
1623
|
+
type: Img,
|
|
1624
|
+
className: FileIcon,
|
|
1625
|
+
src: icon,
|
|
1626
|
+
role: None,
|
|
1627
|
+
childCount: 0
|
|
1628
|
+
};
|
|
1629
|
+
};
|
|
1630
|
+
|
|
1631
|
+
const getIconDom = (fileIcon, symbolName) => {
|
|
1632
|
+
if (fileIcon) {
|
|
1633
|
+
return getFileIconVirtualDom(fileIcon);
|
|
1634
|
+
}
|
|
1635
|
+
return {
|
|
1636
|
+
type: Div,
|
|
1637
|
+
className: `${ColoredMaskIcon} ${symbolName}`,
|
|
1638
|
+
childCount: 0
|
|
1639
|
+
};
|
|
1640
|
+
};
|
|
1641
|
+
|
|
1642
|
+
const Text = 12;
|
|
1643
|
+
const text = data => {
|
|
1644
|
+
return {
|
|
1645
|
+
type: Text,
|
|
1646
|
+
text: data,
|
|
1647
|
+
childCount: 0
|
|
1648
|
+
};
|
|
1649
|
+
};
|
|
1650
|
+
|
|
1651
|
+
const label1 = {
|
|
1652
|
+
type: Div,
|
|
1653
|
+
className: Label,
|
|
1654
|
+
childCount: 1
|
|
1655
|
+
};
|
|
1656
|
+
const completionHighlight = {
|
|
1657
|
+
type: Span,
|
|
1658
|
+
className: EditorCompletionItemHighlight,
|
|
1659
|
+
childCount: 1
|
|
1660
|
+
};
|
|
1661
|
+
const getHighlightedLabelDom = (label, highlights) => {
|
|
1662
|
+
if (highlights.length === 0) {
|
|
1663
|
+
return [label1, text(label)];
|
|
1664
|
+
}
|
|
1665
|
+
const dom = [];
|
|
1666
|
+
const labelDom = {
|
|
1667
|
+
type: Div,
|
|
1668
|
+
className: Label,
|
|
1669
|
+
childCount: 0
|
|
1670
|
+
};
|
|
1671
|
+
dom.push(labelDom);
|
|
1672
|
+
let position = 0;
|
|
1673
|
+
for (let i = 0; i < highlights.length; i += 2) {
|
|
1674
|
+
const highlightStart = highlights[i];
|
|
1675
|
+
const highlightEnd = highlights[i + 1];
|
|
1676
|
+
if (position < highlightStart) {
|
|
1677
|
+
const beforeText = label.slice(position, highlightStart);
|
|
1678
|
+
labelDom.childCount++;
|
|
1679
|
+
dom.push(text(beforeText));
|
|
1680
|
+
}
|
|
1681
|
+
const highlightText = label.slice(highlightStart, highlightEnd);
|
|
1682
|
+
labelDom.childCount++;
|
|
1683
|
+
dom.push(completionHighlight, text(highlightText));
|
|
1684
|
+
position = highlightEnd;
|
|
1685
|
+
}
|
|
1686
|
+
if (position < label.length) {
|
|
1687
|
+
const afterText = label.slice(position);
|
|
1688
|
+
labelDom.childCount++;
|
|
1689
|
+
dom.push(text(afterText));
|
|
1690
|
+
}
|
|
1691
|
+
return dom;
|
|
1692
|
+
};
|
|
1693
|
+
|
|
1694
|
+
const getCompletionItemVirtualDom = visibleItem => {
|
|
1695
|
+
const {
|
|
1696
|
+
top,
|
|
1697
|
+
label,
|
|
1698
|
+
symbolName,
|
|
1699
|
+
highlights,
|
|
1700
|
+
focused,
|
|
1701
|
+
deprecated,
|
|
1702
|
+
fileIcon
|
|
1703
|
+
} = visibleItem;
|
|
1704
|
+
let className = EditorCompletionItem;
|
|
1705
|
+
if (focused) {
|
|
1706
|
+
className += ' ' + EditorCompletionItemFocused;
|
|
1707
|
+
}
|
|
1708
|
+
if (deprecated) {
|
|
1709
|
+
className += ' ' + EditorCompletionItemDeprecated;
|
|
1710
|
+
}
|
|
1711
|
+
return [{
|
|
1712
|
+
type: Div,
|
|
1713
|
+
role: Option,
|
|
1714
|
+
className,
|
|
1715
|
+
top,
|
|
1716
|
+
childCount: 2
|
|
1717
|
+
}, getIconDom(fileIcon, symbolName), ...getHighlightedLabelDom(label, highlights)];
|
|
1718
|
+
};
|
|
1719
|
+
|
|
1720
|
+
const getCompletionItemsVirtualDom = visibleItems => {
|
|
1721
|
+
if (visibleItems.length === 0) {
|
|
1722
|
+
return [{
|
|
1723
|
+
type: Div,
|
|
1724
|
+
childCount: 1
|
|
1725
|
+
}, text(noResults())];
|
|
1726
|
+
}
|
|
1727
|
+
const root = {
|
|
1728
|
+
type: Div,
|
|
1729
|
+
childCount: visibleItems.length
|
|
1730
|
+
};
|
|
1731
|
+
const dom = [root, ...visibleItems.flatMap(getCompletionItemVirtualDom)];
|
|
1732
|
+
return dom;
|
|
1733
|
+
};
|
|
1734
|
+
|
|
1735
|
+
const Property = 1;
|
|
1736
|
+
const Value = 2;
|
|
1737
|
+
const Function = 3;
|
|
1738
|
+
const Variable = 4;
|
|
1739
|
+
const Keyword = 5;
|
|
1740
|
+
const Folder = 6;
|
|
1741
|
+
const File = 7;
|
|
1742
|
+
const Field = 8;
|
|
1743
|
+
|
|
1744
|
+
const SymbolProperty = 'SymbolProperty';
|
|
1745
|
+
const SymbolValue = 'SymbolValue';
|
|
1746
|
+
const SymbolFunction = 'SymbolFunction';
|
|
1747
|
+
const SymbolVariable = 'SymbolVariable';
|
|
1748
|
+
const SymbolKeyword = 'SymbolKeyword';
|
|
1749
|
+
const SymbolDefault = 'SymbolDefault';
|
|
1750
|
+
const SymbolField = 'SymbolField';
|
|
1751
|
+
const SymbolNone = '';
|
|
1752
|
+
|
|
1753
|
+
const getSymbolName = kind => {
|
|
1754
|
+
switch (kind) {
|
|
1755
|
+
case Property:
|
|
1756
|
+
return SymbolProperty;
|
|
1757
|
+
case Value:
|
|
1758
|
+
return SymbolValue;
|
|
1759
|
+
case Function:
|
|
1760
|
+
return SymbolFunction;
|
|
1761
|
+
case Variable:
|
|
1762
|
+
return SymbolVariable;
|
|
1763
|
+
case Keyword:
|
|
1764
|
+
return SymbolKeyword;
|
|
1765
|
+
case Field:
|
|
1766
|
+
return SymbolField;
|
|
1767
|
+
case File:
|
|
1768
|
+
return SymbolNone;
|
|
1769
|
+
default:
|
|
1770
|
+
return SymbolDefault;
|
|
1771
|
+
}
|
|
1772
|
+
};
|
|
1773
|
+
|
|
1774
|
+
// TODO
|
|
1775
|
+
const getCompletionFileIcon = kind => {
|
|
1776
|
+
switch (kind) {
|
|
1777
|
+
case File:
|
|
1778
|
+
return EmptyString;
|
|
1779
|
+
case Folder:
|
|
1780
|
+
return EmptyString;
|
|
1781
|
+
default:
|
|
1782
|
+
return EmptyString;
|
|
1783
|
+
}
|
|
1784
|
+
};
|
|
1785
|
+
|
|
1786
|
+
const getHighlights = item => {
|
|
1787
|
+
const {
|
|
1788
|
+
matches
|
|
1789
|
+
} = item;
|
|
1790
|
+
return matches.slice(1);
|
|
1791
|
+
};
|
|
1792
|
+
|
|
1793
|
+
const getLabel = item => {
|
|
1794
|
+
return item.label;
|
|
1795
|
+
};
|
|
1796
|
+
const getVisibleIem = (item, itemHeight, leadingWord, i, focusedIndex) => {
|
|
1797
|
+
return {
|
|
1798
|
+
label: getLabel(item),
|
|
1799
|
+
symbolName: getSymbolName(item.kind),
|
|
1800
|
+
top: i * itemHeight,
|
|
1801
|
+
highlights: getHighlights(item),
|
|
1802
|
+
focused: i === focusedIndex,
|
|
1803
|
+
deprecated: item.flags & Deprecated,
|
|
1804
|
+
fileIcon: getCompletionFileIcon(item.kind)
|
|
1805
|
+
};
|
|
1806
|
+
};
|
|
1807
|
+
|
|
1808
|
+
const getVisibleItems = (filteredItems, itemHeight, leadingWord, minLineY, maxLineY, focusedIndex) => {
|
|
1809
|
+
const visibleItems = [];
|
|
1810
|
+
for (let i = minLineY; i < maxLineY; i++) {
|
|
1811
|
+
const filteredItem = filteredItems[i];
|
|
1812
|
+
visibleItems.push(getVisibleIem(filteredItem, itemHeight, leadingWord, i, focusedIndex));
|
|
1813
|
+
}
|
|
1814
|
+
return visibleItems;
|
|
1815
|
+
};
|
|
1816
|
+
|
|
1817
|
+
const renderItems = (oldState, newState) => {
|
|
1818
|
+
const {
|
|
1819
|
+
uid
|
|
1820
|
+
} = newState;
|
|
1821
|
+
const visibleItems = getVisibleItems(newState.items, newState.itemHeight, newState.leadingWord, newState.minLineY, newState.maxLineY, newState.focusedIndex);
|
|
1822
|
+
const dom = getCompletionItemsVirtualDom(visibleItems);
|
|
1823
|
+
return [SetDom2, uid, dom];
|
|
1824
|
+
};
|
|
1825
|
+
|
|
1506
1826
|
const getRenderer = diffType => {
|
|
1507
1827
|
switch (diffType) {
|
|
1508
1828
|
case RenderContent:
|
|
1509
1829
|
return renderContent;
|
|
1830
|
+
case RenderBounds:
|
|
1831
|
+
return renderBounds;
|
|
1832
|
+
case RenderEventListeners:
|
|
1833
|
+
return renderEventListeners;
|
|
1834
|
+
case RenderItems:
|
|
1835
|
+
return renderItems;
|
|
1510
1836
|
default:
|
|
1511
1837
|
throw new Error('unknown renderer');
|
|
1512
1838
|
}
|
|
@@ -1542,7 +1868,8 @@ const commandMap = {
|
|
|
1542
1868
|
'Completions.loadContent': wrapCommand(loadContent),
|
|
1543
1869
|
'Completions.render2': render2,
|
|
1544
1870
|
'Completions.terminate': terminate,
|
|
1545
|
-
'Completions.initialize': initialize
|
|
1871
|
+
'Completions.initialize': initialize,
|
|
1872
|
+
'Completions.handleEditorType': handleEditorType
|
|
1546
1873
|
};
|
|
1547
1874
|
|
|
1548
1875
|
const listen = async () => {
|