@lvce-editor/completion-worker 1.2.0 → 1.4.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 +531 -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,209 @@ 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
|
+
return invoke$1('Editor.getWordAtOffset2', editorUid);
|
|
1452
1510
|
};
|
|
1453
1511
|
|
|
1454
1512
|
const loadContent = async state => {
|
|
@@ -1459,7 +1517,7 @@ const loadContent = async state => {
|
|
|
1459
1517
|
editorLanguageId
|
|
1460
1518
|
} = state;
|
|
1461
1519
|
const unfilteredItems = await getCompletions(editorUid, editorLanguageId);
|
|
1462
|
-
const wordAtOffset = await getWordAtOffset();
|
|
1520
|
+
const wordAtOffset = await getWordAtOffset(editorUid);
|
|
1463
1521
|
const items = filterCompletionItems(unfilteredItems, wordAtOffset);
|
|
1464
1522
|
const {
|
|
1465
1523
|
rowIndex,
|
|
@@ -1491,9 +1549,21 @@ const loadContent = async state => {
|
|
|
1491
1549
|
};
|
|
1492
1550
|
};
|
|
1493
1551
|
|
|
1494
|
-
const
|
|
1495
|
-
|
|
1552
|
+
const SetBounds = 'Viewlet.setBounds';
|
|
1496
1553
|
const SetDom2 = 'Viewlet.setDom2';
|
|
1554
|
+
const SetUid = 'Viewlet.setUid';
|
|
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,303 @@ 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 ColoredMaskIcon = 'ColoredMaskIcon';
|
|
1589
|
+
const EditorCompletion = 'EditorCompletion';
|
|
1590
|
+
const EditorCompletionItem = 'EditorCompletionItem';
|
|
1591
|
+
const EditorCompletionItemDeprecated = 'EditorCompletionItemDeprecated';
|
|
1592
|
+
const EditorCompletionItemFocused = 'EditorCompletionItemFocused';
|
|
1593
|
+
const EditorCompletionItemHighlight = 'EditorCompletionItemHighlight';
|
|
1594
|
+
const FileIcon = 'FileIcon';
|
|
1595
|
+
const Label = 'Label';
|
|
1596
|
+
const Viewlet = 'Viewlet';
|
|
1597
|
+
|
|
1598
|
+
const None = 'none';
|
|
1599
|
+
const Option = 'option';
|
|
1600
|
+
|
|
1601
|
+
const Div = 4;
|
|
1602
|
+
const Span = 8;
|
|
1603
|
+
const Img = 17;
|
|
1604
|
+
|
|
1605
|
+
const getFileIconVirtualDom = icon => {
|
|
1606
|
+
return {
|
|
1607
|
+
type: Img,
|
|
1608
|
+
className: FileIcon,
|
|
1609
|
+
src: icon,
|
|
1610
|
+
role: None,
|
|
1611
|
+
childCount: 0
|
|
1612
|
+
};
|
|
1613
|
+
};
|
|
1614
|
+
|
|
1615
|
+
const getIconDom = (fileIcon, symbolName) => {
|
|
1616
|
+
if (fileIcon) {
|
|
1617
|
+
return getFileIconVirtualDom(fileIcon);
|
|
1618
|
+
}
|
|
1619
|
+
return {
|
|
1620
|
+
type: Div,
|
|
1621
|
+
className: `${ColoredMaskIcon} ${symbolName}`,
|
|
1622
|
+
childCount: 0
|
|
1623
|
+
};
|
|
1624
|
+
};
|
|
1625
|
+
|
|
1626
|
+
const mergeClassNames = (...classNames) => {
|
|
1627
|
+
return classNames.filter(Boolean).join(' ');
|
|
1628
|
+
};
|
|
1629
|
+
const Text = 12;
|
|
1630
|
+
const text = data => {
|
|
1631
|
+
return {
|
|
1632
|
+
type: Text,
|
|
1633
|
+
text: data,
|
|
1634
|
+
childCount: 0
|
|
1635
|
+
};
|
|
1636
|
+
};
|
|
1637
|
+
|
|
1638
|
+
const label1 = {
|
|
1639
|
+
type: Div,
|
|
1640
|
+
className: Label,
|
|
1641
|
+
childCount: 1
|
|
1642
|
+
};
|
|
1643
|
+
const completionHighlight = {
|
|
1644
|
+
type: Span,
|
|
1645
|
+
className: EditorCompletionItemHighlight,
|
|
1646
|
+
childCount: 1
|
|
1647
|
+
};
|
|
1648
|
+
const getHighlightedLabelDom = (label, highlights) => {
|
|
1649
|
+
if (highlights.length === 0) {
|
|
1650
|
+
return [label1, text(label)];
|
|
1651
|
+
}
|
|
1652
|
+
const dom = [];
|
|
1653
|
+
const labelDom = {
|
|
1654
|
+
type: Div,
|
|
1655
|
+
className: Label,
|
|
1656
|
+
childCount: 0
|
|
1657
|
+
};
|
|
1658
|
+
dom.push(labelDom);
|
|
1659
|
+
let position = 0;
|
|
1660
|
+
for (let i = 0; i < highlights.length; i += 2) {
|
|
1661
|
+
const highlightStart = highlights[i];
|
|
1662
|
+
const highlightEnd = highlights[i + 1];
|
|
1663
|
+
if (position < highlightStart) {
|
|
1664
|
+
const beforeText = label.slice(position, highlightStart);
|
|
1665
|
+
labelDom.childCount++;
|
|
1666
|
+
dom.push(text(beforeText));
|
|
1667
|
+
}
|
|
1668
|
+
const highlightText = label.slice(highlightStart, highlightEnd);
|
|
1669
|
+
labelDom.childCount++;
|
|
1670
|
+
dom.push(completionHighlight, text(highlightText));
|
|
1671
|
+
position = highlightEnd;
|
|
1672
|
+
}
|
|
1673
|
+
if (position < label.length) {
|
|
1674
|
+
const afterText = label.slice(position);
|
|
1675
|
+
labelDom.childCount++;
|
|
1676
|
+
dom.push(text(afterText));
|
|
1677
|
+
}
|
|
1678
|
+
return dom;
|
|
1679
|
+
};
|
|
1680
|
+
|
|
1681
|
+
const getCompletionItemVirtualDom = visibleItem => {
|
|
1682
|
+
const {
|
|
1683
|
+
top,
|
|
1684
|
+
label,
|
|
1685
|
+
symbolName,
|
|
1686
|
+
highlights,
|
|
1687
|
+
focused,
|
|
1688
|
+
deprecated,
|
|
1689
|
+
fileIcon
|
|
1690
|
+
} = visibleItem;
|
|
1691
|
+
let className = EditorCompletionItem;
|
|
1692
|
+
if (focused) {
|
|
1693
|
+
className += ' ' + EditorCompletionItemFocused;
|
|
1694
|
+
}
|
|
1695
|
+
if (deprecated) {
|
|
1696
|
+
className += ' ' + EditorCompletionItemDeprecated;
|
|
1697
|
+
}
|
|
1698
|
+
return [{
|
|
1699
|
+
type: Div,
|
|
1700
|
+
role: Option,
|
|
1701
|
+
className,
|
|
1702
|
+
top,
|
|
1703
|
+
childCount: 2
|
|
1704
|
+
}, getIconDom(fileIcon, symbolName), ...getHighlightedLabelDom(label, highlights)];
|
|
1705
|
+
};
|
|
1706
|
+
|
|
1707
|
+
const emptyObject = {};
|
|
1708
|
+
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
1709
|
+
const i18nString = (key, placeholders = emptyObject) => {
|
|
1710
|
+
if (placeholders === emptyObject) {
|
|
1711
|
+
return key;
|
|
1712
|
+
}
|
|
1713
|
+
const replacer = (match, rest) => {
|
|
1714
|
+
return placeholders[rest];
|
|
1715
|
+
};
|
|
1716
|
+
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
1717
|
+
};
|
|
1718
|
+
|
|
1719
|
+
const NoResults = 'No Results';
|
|
1720
|
+
|
|
1721
|
+
const noResults = () => {
|
|
1722
|
+
return i18nString(NoResults);
|
|
1723
|
+
};
|
|
1724
|
+
|
|
1725
|
+
const getNoResultsVirtualDom = () => {
|
|
1726
|
+
return [{
|
|
1727
|
+
type: Div,
|
|
1728
|
+
childCount: 1
|
|
1729
|
+
}, text(noResults())];
|
|
1730
|
+
};
|
|
1731
|
+
|
|
1732
|
+
const getCompletionItemsVirtualDom = visibleItems => {
|
|
1733
|
+
if (visibleItems.length === 0) {
|
|
1734
|
+
return getNoResultsVirtualDom();
|
|
1735
|
+
}
|
|
1736
|
+
const root = {
|
|
1737
|
+
type: Div,
|
|
1738
|
+
childCount: visibleItems.length
|
|
1739
|
+
};
|
|
1740
|
+
const dom = [root, ...visibleItems.flatMap(getCompletionItemVirtualDom)];
|
|
1741
|
+
return dom;
|
|
1742
|
+
};
|
|
1743
|
+
|
|
1744
|
+
const getCompletionVirtualDom = visibleItems => {
|
|
1745
|
+
return [{
|
|
1746
|
+
type: Div,
|
|
1747
|
+
className: mergeClassNames(Viewlet, EditorCompletion),
|
|
1748
|
+
id: 'Completions',
|
|
1749
|
+
childCount: 1
|
|
1750
|
+
}, {
|
|
1751
|
+
type: Div,
|
|
1752
|
+
className: 'ListItems',
|
|
1753
|
+
role: 'listbox',
|
|
1754
|
+
ariaLabel: 'Suggest',
|
|
1755
|
+
childCount: 1
|
|
1756
|
+
}, ...getCompletionItemsVirtualDom(visibleItems)
|
|
1757
|
+
|
|
1758
|
+
// TODO render scrollbar
|
|
1759
|
+
];
|
|
1760
|
+
};
|
|
1761
|
+
|
|
1762
|
+
const Property = 1;
|
|
1763
|
+
const Value = 2;
|
|
1764
|
+
const Function = 3;
|
|
1765
|
+
const Variable = 4;
|
|
1766
|
+
const Keyword = 5;
|
|
1767
|
+
const Folder = 6;
|
|
1768
|
+
const File = 7;
|
|
1769
|
+
const Field = 8;
|
|
1770
|
+
|
|
1771
|
+
const SymbolProperty = 'SymbolProperty';
|
|
1772
|
+
const SymbolValue = 'SymbolValue';
|
|
1773
|
+
const SymbolFunction = 'SymbolFunction';
|
|
1774
|
+
const SymbolVariable = 'SymbolVariable';
|
|
1775
|
+
const SymbolKeyword = 'SymbolKeyword';
|
|
1776
|
+
const SymbolDefault = 'SymbolDefault';
|
|
1777
|
+
const SymbolField = 'SymbolField';
|
|
1778
|
+
const SymbolNone = '';
|
|
1779
|
+
|
|
1780
|
+
const getSymbolName = kind => {
|
|
1781
|
+
switch (kind) {
|
|
1782
|
+
case Property:
|
|
1783
|
+
return SymbolProperty;
|
|
1784
|
+
case Value:
|
|
1785
|
+
return SymbolValue;
|
|
1786
|
+
case Function:
|
|
1787
|
+
return SymbolFunction;
|
|
1788
|
+
case Variable:
|
|
1789
|
+
return SymbolVariable;
|
|
1790
|
+
case Keyword:
|
|
1791
|
+
return SymbolKeyword;
|
|
1792
|
+
case Field:
|
|
1793
|
+
return SymbolField;
|
|
1794
|
+
case File:
|
|
1795
|
+
return SymbolNone;
|
|
1796
|
+
default:
|
|
1797
|
+
return SymbolDefault;
|
|
1798
|
+
}
|
|
1799
|
+
};
|
|
1800
|
+
|
|
1801
|
+
// TODO
|
|
1802
|
+
const getCompletionFileIcon = kind => {
|
|
1803
|
+
switch (kind) {
|
|
1804
|
+
case File:
|
|
1805
|
+
return EmptyString;
|
|
1806
|
+
case Folder:
|
|
1807
|
+
return EmptyString;
|
|
1808
|
+
default:
|
|
1809
|
+
return EmptyString;
|
|
1810
|
+
}
|
|
1811
|
+
};
|
|
1812
|
+
|
|
1813
|
+
const getHighlights = item => {
|
|
1814
|
+
const {
|
|
1815
|
+
matches
|
|
1816
|
+
} = item;
|
|
1817
|
+
return matches.slice(1);
|
|
1818
|
+
};
|
|
1819
|
+
|
|
1820
|
+
const getLabel = item => {
|
|
1821
|
+
return item.label;
|
|
1822
|
+
};
|
|
1823
|
+
const getVisibleIem = (item, itemHeight, leadingWord, i, focusedIndex) => {
|
|
1824
|
+
return {
|
|
1825
|
+
label: getLabel(item),
|
|
1826
|
+
symbolName: getSymbolName(item.kind),
|
|
1827
|
+
top: i * itemHeight,
|
|
1828
|
+
highlights: getHighlights(item),
|
|
1829
|
+
focused: i === focusedIndex,
|
|
1830
|
+
deprecated: item.flags & Deprecated,
|
|
1831
|
+
fileIcon: getCompletionFileIcon(item.kind)
|
|
1832
|
+
};
|
|
1833
|
+
};
|
|
1834
|
+
|
|
1835
|
+
const getVisibleItems = (filteredItems, itemHeight, leadingWord, minLineY, maxLineY, focusedIndex) => {
|
|
1836
|
+
const visibleItems = [];
|
|
1837
|
+
for (let i = minLineY; i < maxLineY; i++) {
|
|
1838
|
+
const filteredItem = filteredItems[i];
|
|
1839
|
+
visibleItems.push(getVisibleIem(filteredItem, itemHeight, leadingWord, i, focusedIndex));
|
|
1840
|
+
}
|
|
1841
|
+
return visibleItems;
|
|
1842
|
+
};
|
|
1843
|
+
|
|
1844
|
+
const renderItems = (oldState, newState) => {
|
|
1845
|
+
const {
|
|
1846
|
+
uid
|
|
1847
|
+
} = newState;
|
|
1848
|
+
const visibleItems = getVisibleItems(newState.items, newState.itemHeight, newState.leadingWord, newState.minLineY, newState.maxLineY, newState.focusedIndex);
|
|
1849
|
+
const dom = getCompletionVirtualDom(visibleItems);
|
|
1850
|
+
return [SetDom2, uid, dom];
|
|
1851
|
+
};
|
|
1852
|
+
|
|
1853
|
+
const renderUid = (oldState, newState) => {
|
|
1854
|
+
const {
|
|
1855
|
+
uid,
|
|
1856
|
+
editorUid
|
|
1857
|
+
} = newState;
|
|
1858
|
+
return [SetUid, uid, editorUid];
|
|
1859
|
+
};
|
|
1860
|
+
|
|
1506
1861
|
const getRenderer = diffType => {
|
|
1507
1862
|
switch (diffType) {
|
|
1508
1863
|
case RenderContent:
|
|
1509
1864
|
return renderContent;
|
|
1865
|
+
case RenderBounds:
|
|
1866
|
+
return renderBounds;
|
|
1867
|
+
case RenderEventListeners:
|
|
1868
|
+
return renderEventListeners;
|
|
1869
|
+
case RenderUid:
|
|
1870
|
+
return renderUid;
|
|
1871
|
+
case RenderItems:
|
|
1872
|
+
return renderItems;
|
|
1510
1873
|
default:
|
|
1511
1874
|
throw new Error('unknown renderer');
|
|
1512
1875
|
}
|
|
@@ -1542,7 +1905,8 @@ const commandMap = {
|
|
|
1542
1905
|
'Completions.loadContent': wrapCommand(loadContent),
|
|
1543
1906
|
'Completions.render2': render2,
|
|
1544
1907
|
'Completions.terminate': terminate,
|
|
1545
|
-
'Completions.initialize': initialize
|
|
1908
|
+
'Completions.initialize': initialize,
|
|
1909
|
+
'Completions.handleEditorType': handleEditorType
|
|
1546
1910
|
};
|
|
1547
1911
|
|
|
1548
1912
|
const listen = async () => {
|