@lvce-editor/completion-worker 1.1.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 +502 -185
- package/package.json +1 -1
|
@@ -1020,7 +1020,7 @@ const {
|
|
|
1020
1020
|
wrapCommand
|
|
1021
1021
|
} = create$2();
|
|
1022
1022
|
|
|
1023
|
-
const create$1 = (uid, x, y, width, height,
|
|
1023
|
+
const create$1 = (uid, x, y, width, height, editorUid, editorLanguageId) => {
|
|
1024
1024
|
const state = {
|
|
1025
1025
|
uid,
|
|
1026
1026
|
items: [],
|
|
@@ -1039,13 +1039,37 @@ const create$1 = (uid, x, y, width, height, parentUid) => {
|
|
|
1039
1039
|
headerHeight: 0,
|
|
1040
1040
|
leadingWord: '',
|
|
1041
1041
|
unfilteredItems: [],
|
|
1042
|
-
version: 0
|
|
1042
|
+
version: 0,
|
|
1043
|
+
editorUid,
|
|
1044
|
+
editorLanguageId
|
|
1043
1045
|
};
|
|
1044
1046
|
set$2(uid, state, state);
|
|
1045
1047
|
};
|
|
1046
1048
|
|
|
1047
|
-
const
|
|
1048
|
-
|
|
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];
|
|
1049
1073
|
|
|
1050
1074
|
const diff = (oldState, newState) => {
|
|
1051
1075
|
const diffResult = [];
|
|
@@ -1073,157 +1097,6 @@ const getCommandIds = () => {
|
|
|
1073
1097
|
return commandIds;
|
|
1074
1098
|
};
|
|
1075
1099
|
|
|
1076
|
-
const getPortTuple = () => {
|
|
1077
|
-
const {
|
|
1078
|
-
port1,
|
|
1079
|
-
port2
|
|
1080
|
-
} = new MessageChannel();
|
|
1081
|
-
return {
|
|
1082
|
-
port1,
|
|
1083
|
-
port2
|
|
1084
|
-
};
|
|
1085
|
-
};
|
|
1086
|
-
|
|
1087
|
-
const rpcs = Object.create(null);
|
|
1088
|
-
const set$9 = (id, rpc) => {
|
|
1089
|
-
rpcs[id] = rpc;
|
|
1090
|
-
};
|
|
1091
|
-
const get = id => {
|
|
1092
|
-
return rpcs[id];
|
|
1093
|
-
};
|
|
1094
|
-
|
|
1095
|
-
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
1096
|
-
|
|
1097
|
-
const create = rpcId => {
|
|
1098
|
-
return {
|
|
1099
|
-
// @ts-ignore
|
|
1100
|
-
invoke(method, ...params) {
|
|
1101
|
-
const rpc = get(rpcId);
|
|
1102
|
-
// @ts-ignore
|
|
1103
|
-
return rpc.invoke(method, ...params);
|
|
1104
|
-
},
|
|
1105
|
-
// @ts-ignore
|
|
1106
|
-
invokeAndTransfer(method, ...params) {
|
|
1107
|
-
const rpc = get(rpcId);
|
|
1108
|
-
// @ts-ignore
|
|
1109
|
-
return rpc.invokeAndTransfer(method, ...params);
|
|
1110
|
-
},
|
|
1111
|
-
set(rpc) {
|
|
1112
|
-
set$9(rpcId, rpc);
|
|
1113
|
-
}
|
|
1114
|
-
};
|
|
1115
|
-
};
|
|
1116
|
-
const EditorWorker$1 = 99;
|
|
1117
|
-
const ExtensionHostWorker = 44;
|
|
1118
|
-
const {
|
|
1119
|
-
invoke: invoke$8,
|
|
1120
|
-
invokeAndTransfer: invokeAndTransfer$8,
|
|
1121
|
-
set: set$8
|
|
1122
|
-
} = create(EditorWorker$1);
|
|
1123
|
-
const EditorWorker = {
|
|
1124
|
-
__proto__: null,
|
|
1125
|
-
invoke: invoke$8,
|
|
1126
|
-
invokeAndTransfer: invokeAndTransfer$8,
|
|
1127
|
-
set: set$8
|
|
1128
|
-
};
|
|
1129
|
-
const {
|
|
1130
|
-
invoke: invoke$6,
|
|
1131
|
-
set: set$6
|
|
1132
|
-
} = create(ExtensionHostWorker);
|
|
1133
|
-
const ExtensionHost = {
|
|
1134
|
-
__proto__: null,
|
|
1135
|
-
invoke: invoke$6,
|
|
1136
|
-
set: set$6
|
|
1137
|
-
};
|
|
1138
|
-
|
|
1139
|
-
const {
|
|
1140
|
-
invoke: invoke$1,
|
|
1141
|
-
set: set$1,
|
|
1142
|
-
invokeAndTransfer
|
|
1143
|
-
} = EditorWorker;
|
|
1144
|
-
|
|
1145
|
-
const sendMessagePortToExtensionHostWorker = async port => {
|
|
1146
|
-
const command = 'HandleMessagePort.handleMessagePort2';
|
|
1147
|
-
// @ts-ignore
|
|
1148
|
-
await invokeAndTransfer(
|
|
1149
|
-
// @ts-ignore
|
|
1150
|
-
'SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, 0 // TODO
|
|
1151
|
-
);
|
|
1152
|
-
};
|
|
1153
|
-
|
|
1154
|
-
const createExtensionHostRpc = async () => {
|
|
1155
|
-
try {
|
|
1156
|
-
const {
|
|
1157
|
-
port1,
|
|
1158
|
-
port2
|
|
1159
|
-
} = getPortTuple();
|
|
1160
|
-
await sendMessagePortToExtensionHostWorker(port2);
|
|
1161
|
-
const rpc = await PlainMessagePortRpcParent.create({
|
|
1162
|
-
commandMap: {},
|
|
1163
|
-
messagePort: port1
|
|
1164
|
-
});
|
|
1165
|
-
return rpc;
|
|
1166
|
-
} catch (error) {
|
|
1167
|
-
throw new VError(error, `Failed to create extension host rpc`);
|
|
1168
|
-
}
|
|
1169
|
-
};
|
|
1170
|
-
|
|
1171
|
-
const {
|
|
1172
|
-
invoke,
|
|
1173
|
-
set
|
|
1174
|
-
} = ExtensionHost;
|
|
1175
|
-
|
|
1176
|
-
const initialize = async () => {
|
|
1177
|
-
const rpc = await createExtensionHostRpc();
|
|
1178
|
-
set(rpc);
|
|
1179
|
-
};
|
|
1180
|
-
|
|
1181
|
-
const OnCompletion = 'onCompletion';
|
|
1182
|
-
|
|
1183
|
-
const CompletionExecute = 'ExtensionHostCompletion.execute';
|
|
1184
|
-
|
|
1185
|
-
// TODO add tests for this
|
|
1186
|
-
const activateByEvent = async event => {
|
|
1187
|
-
// @ts-ignore
|
|
1188
|
-
await invoke$1('ActivateByEvent.activateByEvent', event);
|
|
1189
|
-
};
|
|
1190
|
-
|
|
1191
|
-
const execute = async ({
|
|
1192
|
-
editor,
|
|
1193
|
-
args,
|
|
1194
|
-
event,
|
|
1195
|
-
method,
|
|
1196
|
-
noProviderFoundMessage,
|
|
1197
|
-
noProviderFoundResult = undefined
|
|
1198
|
-
}) => {
|
|
1199
|
-
const fullEvent = `${event}:${editor.languageId}`;
|
|
1200
|
-
await activateByEvent(fullEvent);
|
|
1201
|
-
const result = await invoke(method, editor.uid, ...args);
|
|
1202
|
-
return result;
|
|
1203
|
-
};
|
|
1204
|
-
|
|
1205
|
-
const executeCompletionProvider = async (editor, offset) => {
|
|
1206
|
-
return execute({
|
|
1207
|
-
editor,
|
|
1208
|
-
event: OnCompletion,
|
|
1209
|
-
method: CompletionExecute,
|
|
1210
|
-
args: [offset],
|
|
1211
|
-
noProviderFoundMessage: 'no completion provider found',
|
|
1212
|
-
noProviderFoundResult: []});
|
|
1213
|
-
};
|
|
1214
|
-
|
|
1215
|
-
const getOffsetAtCursor = editor => {
|
|
1216
|
-
// TODO
|
|
1217
|
-
return 0;
|
|
1218
|
-
};
|
|
1219
|
-
|
|
1220
|
-
// TODO possible to do this with events/state machine instead of promises -> enables canceling operations / concurrent calls
|
|
1221
|
-
const getCompletions = async editor => {
|
|
1222
|
-
const offset = getOffsetAtCursor();
|
|
1223
|
-
const completions = await executeCompletionProvider(editor, offset);
|
|
1224
|
-
return completions;
|
|
1225
|
-
};
|
|
1226
|
-
|
|
1227
1100
|
const Diagonal = 1;
|
|
1228
1101
|
const Left = 2;
|
|
1229
1102
|
|
|
@@ -1420,12 +1293,6 @@ const filterCompletionItems = (completionItems, word) => {
|
|
|
1420
1293
|
return filteredCompletions;
|
|
1421
1294
|
};
|
|
1422
1295
|
|
|
1423
|
-
const getFinalDeltaY = (height, itemHeight, itemsLength) => {
|
|
1424
|
-
const contentHeight = itemsLength * itemHeight;
|
|
1425
|
-
const finalDeltaY = Math.max(contentHeight - height, 0);
|
|
1426
|
-
return finalDeltaY;
|
|
1427
|
-
};
|
|
1428
|
-
|
|
1429
1296
|
const getListHeight = (itemsLength, itemHeight, maxHeight) => {
|
|
1430
1297
|
number(itemsLength);
|
|
1431
1298
|
number(itemHeight);
|
|
@@ -1437,46 +1304,229 @@ const getListHeight = (itemsLength, itemHeight, maxHeight) => {
|
|
|
1437
1304
|
return Math.min(totalHeight, maxHeight);
|
|
1438
1305
|
};
|
|
1439
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
|
+
|
|
1440
1365
|
const getPositionAtCursor = async parentUid => {
|
|
1441
1366
|
const position = await invoke$1('Editor.getPositionAtCursor', parentUid);
|
|
1442
1367
|
return position;
|
|
1443
1368
|
};
|
|
1444
1369
|
|
|
1445
|
-
const
|
|
1446
|
-
|
|
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 => {
|
|
1447
1376
|
const {
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
const
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
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`);
|
|
1458
1441
|
}
|
|
1459
|
-
|
|
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 => {
|
|
1491
|
+
// TODO ask editor worker
|
|
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);
|
|
1460
1511
|
};
|
|
1461
1512
|
|
|
1462
1513
|
const loadContent = async state => {
|
|
1463
|
-
const editor = {}; // TODO
|
|
1464
1514
|
const {
|
|
1465
1515
|
itemHeight,
|
|
1466
|
-
maxHeight
|
|
1516
|
+
maxHeight,
|
|
1517
|
+
editorUid,
|
|
1518
|
+
editorLanguageId
|
|
1467
1519
|
} = state;
|
|
1468
|
-
const unfilteredItems = await getCompletions(
|
|
1469
|
-
const wordAtOffset = getWordAtOffset(
|
|
1520
|
+
const unfilteredItems = await getCompletions(editorUid, editorLanguageId);
|
|
1521
|
+
const wordAtOffset = await getWordAtOffset(editorUid);
|
|
1470
1522
|
const items = filterCompletionItems(unfilteredItems, wordAtOffset);
|
|
1471
1523
|
const {
|
|
1472
1524
|
rowIndex,
|
|
1473
1525
|
columnIndex,
|
|
1474
1526
|
x,
|
|
1475
1527
|
y
|
|
1476
|
-
} = await getPositionAtCursor(
|
|
1528
|
+
} = await getPositionAtCursor(editorUid);
|
|
1477
1529
|
const newMaxLineY = Math.min(items.length, 8);
|
|
1478
|
-
editor.widgets = editor.widgets || [];
|
|
1479
|
-
// editor.widgets.push(ViewletModuleId.EditorCompletion)
|
|
1480
1530
|
const itemsLength = items.length;
|
|
1481
1531
|
const newFocusedIndex = itemsLength === 0 ? -1 : 0;
|
|
1482
1532
|
const total = items.length;
|
|
@@ -1496,14 +1546,24 @@ const loadContent = async state => {
|
|
|
1496
1546
|
// @ts-ignore
|
|
1497
1547
|
rowIndex,
|
|
1498
1548
|
columnIndex,
|
|
1499
|
-
// editorUid,
|
|
1500
1549
|
width: 200
|
|
1501
1550
|
};
|
|
1502
1551
|
};
|
|
1503
1552
|
|
|
1504
|
-
const
|
|
1505
|
-
|
|
1553
|
+
const SetBounds = 'Viewlet.setBounds';
|
|
1506
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
|
+
};
|
|
1507
1567
|
|
|
1508
1568
|
const renderContent = (oldState, newState) => {
|
|
1509
1569
|
const {
|
|
@@ -1513,10 +1573,266 @@ const renderContent = (oldState, newState) => {
|
|
|
1513
1573
|
return [SetDom2, uid, dom];
|
|
1514
1574
|
};
|
|
1515
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
|
+
|
|
1516
1826
|
const getRenderer = diffType => {
|
|
1517
1827
|
switch (diffType) {
|
|
1518
1828
|
case RenderContent:
|
|
1519
1829
|
return renderContent;
|
|
1830
|
+
case RenderBounds:
|
|
1831
|
+
return renderBounds;
|
|
1832
|
+
case RenderEventListeners:
|
|
1833
|
+
return renderEventListeners;
|
|
1834
|
+
case RenderItems:
|
|
1835
|
+
return renderItems;
|
|
1520
1836
|
default:
|
|
1521
1837
|
throw new Error('unknown renderer');
|
|
1522
1838
|
}
|
|
@@ -1552,7 +1868,8 @@ const commandMap = {
|
|
|
1552
1868
|
'Completions.loadContent': wrapCommand(loadContent),
|
|
1553
1869
|
'Completions.render2': render2,
|
|
1554
1870
|
'Completions.terminate': terminate,
|
|
1555
|
-
'Completions.initialize': initialize
|
|
1871
|
+
'Completions.initialize': initialize,
|
|
1872
|
+
'Completions.handleEditorType': handleEditorType
|
|
1556
1873
|
};
|
|
1557
1874
|
|
|
1558
1875
|
const listen = async () => {
|