@lvce-editor/completion-worker 1.3.0 → 1.5.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 +408 -144
- package/package.json +1 -1
|
@@ -82,6 +82,12 @@ const getType = value => {
|
|
|
82
82
|
return 'unknown';
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
|
+
const object = value => {
|
|
86
|
+
const type = getType(value);
|
|
87
|
+
if (type !== 'object') {
|
|
88
|
+
throw new AssertionError('expected value to be of type object');
|
|
89
|
+
}
|
|
90
|
+
};
|
|
85
91
|
const number = value => {
|
|
86
92
|
const type = getType(value);
|
|
87
93
|
if (type !== 'number') {
|
|
@@ -848,11 +854,11 @@ const commands = Object.create(null);
|
|
|
848
854
|
const register = commandMap => {
|
|
849
855
|
Object.assign(commands, commandMap);
|
|
850
856
|
};
|
|
851
|
-
const getCommand = key => {
|
|
857
|
+
const getCommand$1 = key => {
|
|
852
858
|
return commands[key];
|
|
853
859
|
};
|
|
854
860
|
const execute$1 = (command, ...args) => {
|
|
855
|
-
const fn = getCommand(command);
|
|
861
|
+
const fn = getCommand$1(command);
|
|
856
862
|
if (!fn) {
|
|
857
863
|
throw new Error(`command not found ${command}`);
|
|
858
864
|
}
|
|
@@ -1046,16 +1052,20 @@ const create$1 = (uid, x, y, width, height, editorUid, editorLanguageId) => {
|
|
|
1046
1052
|
set$2(uid, state, state);
|
|
1047
1053
|
};
|
|
1048
1054
|
|
|
1049
|
-
const isEqual$
|
|
1055
|
+
const isEqual$4 = (oldState, newState) => {
|
|
1050
1056
|
return oldState.x === newState.x && oldState.y === newState.y && oldState.width === newState.width && oldState.height === newState.height;
|
|
1051
1057
|
};
|
|
1052
1058
|
|
|
1059
|
+
const isEqual$3 = (oldState, newState) => {
|
|
1060
|
+
return oldState.version === newState.version;
|
|
1061
|
+
};
|
|
1062
|
+
|
|
1053
1063
|
const isEqual$2 = (oldState, newState) => {
|
|
1054
1064
|
return oldState.version === newState.version;
|
|
1055
1065
|
};
|
|
1056
1066
|
|
|
1057
1067
|
const isEqual$1 = (oldState, newState) => {
|
|
1058
|
-
return oldState.items === newState.items;
|
|
1068
|
+
return oldState.items === newState.items && oldState.focusedIndex === newState.focusedIndex;
|
|
1059
1069
|
};
|
|
1060
1070
|
|
|
1061
1071
|
const isEqual = (oldState, newState) => {
|
|
@@ -1067,9 +1077,10 @@ const RenderBounds = 8;
|
|
|
1067
1077
|
const RenderEventListeners = 11;
|
|
1068
1078
|
const RenderUid = 12;
|
|
1069
1079
|
const RenderContent = 13;
|
|
1080
|
+
const RenderFocusContext = 14;
|
|
1070
1081
|
|
|
1071
|
-
const modules = [isEqual$
|
|
1072
|
-
const numbers = [RenderEventListeners, RenderItems, RenderBounds, RenderUid];
|
|
1082
|
+
const modules = [isEqual$3, isEqual$1, isEqual$4, isEqual, isEqual$2];
|
|
1083
|
+
const numbers = [RenderEventListeners, RenderItems, RenderBounds, RenderUid, RenderFocusContext];
|
|
1073
1084
|
|
|
1074
1085
|
const diff = (oldState, newState) => {
|
|
1075
1086
|
const diffResult = [];
|
|
@@ -1091,12 +1102,246 @@ const diff2 = uid => {
|
|
|
1091
1102
|
return diffResult;
|
|
1092
1103
|
};
|
|
1093
1104
|
|
|
1105
|
+
const focusIndex = (state, index) => {
|
|
1106
|
+
const newState = {
|
|
1107
|
+
...state,
|
|
1108
|
+
focusedIndex: index,
|
|
1109
|
+
focused: true
|
|
1110
|
+
};
|
|
1111
|
+
return newState;
|
|
1112
|
+
};
|
|
1113
|
+
|
|
1114
|
+
const focusFirst = state => {
|
|
1115
|
+
const firstIndex = 0;
|
|
1116
|
+
return focusIndex(state, firstIndex);
|
|
1117
|
+
};
|
|
1118
|
+
|
|
1119
|
+
const focusNext = state => {
|
|
1120
|
+
const {
|
|
1121
|
+
focusedIndex
|
|
1122
|
+
} = state;
|
|
1123
|
+
const nextIndex = focusedIndex + 1;
|
|
1124
|
+
return focusIndex(state, nextIndex);
|
|
1125
|
+
};
|
|
1126
|
+
|
|
1127
|
+
const focusPrevious = state => {
|
|
1128
|
+
const previousIndex = state.focusedIndex - 1;
|
|
1129
|
+
return focusIndex(state, previousIndex);
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
const openDetails = async state => {
|
|
1133
|
+
// TODO ask editor worker to add completion details widget
|
|
1134
|
+
return state;
|
|
1135
|
+
};
|
|
1136
|
+
|
|
1137
|
+
const OnCompletion = 'onCompletion';
|
|
1138
|
+
|
|
1139
|
+
const CompletionExecute = 'ExtensionHostCompletion.execute';
|
|
1140
|
+
|
|
1141
|
+
const rpcs = Object.create(null);
|
|
1142
|
+
const set$a = (id, rpc) => {
|
|
1143
|
+
rpcs[id] = rpc;
|
|
1144
|
+
};
|
|
1145
|
+
const get = id => {
|
|
1146
|
+
return rpcs[id];
|
|
1147
|
+
};
|
|
1148
|
+
|
|
1149
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
1150
|
+
|
|
1151
|
+
const create = rpcId => {
|
|
1152
|
+
return {
|
|
1153
|
+
// @ts-ignore
|
|
1154
|
+
invoke(method, ...params) {
|
|
1155
|
+
const rpc = get(rpcId);
|
|
1156
|
+
// @ts-ignore
|
|
1157
|
+
return rpc.invoke(method, ...params);
|
|
1158
|
+
},
|
|
1159
|
+
// @ts-ignore
|
|
1160
|
+
invokeAndTransfer(method, ...params) {
|
|
1161
|
+
const rpc = get(rpcId);
|
|
1162
|
+
// @ts-ignore
|
|
1163
|
+
return rpc.invokeAndTransfer(method, ...params);
|
|
1164
|
+
},
|
|
1165
|
+
set(rpc) {
|
|
1166
|
+
set$a(rpcId, rpc);
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
};
|
|
1170
|
+
const EditorWorker$1 = 99;
|
|
1171
|
+
const ExtensionHostWorker = 44;
|
|
1172
|
+
const {
|
|
1173
|
+
invoke: invoke$9,
|
|
1174
|
+
invokeAndTransfer: invokeAndTransfer$9,
|
|
1175
|
+
set: set$9
|
|
1176
|
+
} = create(EditorWorker$1);
|
|
1177
|
+
const EditorWorker = {
|
|
1178
|
+
__proto__: null,
|
|
1179
|
+
invoke: invoke$9,
|
|
1180
|
+
invokeAndTransfer: invokeAndTransfer$9,
|
|
1181
|
+
set: set$9
|
|
1182
|
+
};
|
|
1183
|
+
const {
|
|
1184
|
+
invoke: invoke$7,
|
|
1185
|
+
set: set$7
|
|
1186
|
+
} = create(ExtensionHostWorker);
|
|
1187
|
+
const ExtensionHost = {
|
|
1188
|
+
__proto__: null,
|
|
1189
|
+
invoke: invoke$7,
|
|
1190
|
+
set: set$7
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
const {
|
|
1194
|
+
invoke: invoke$1,
|
|
1195
|
+
set: set$1,
|
|
1196
|
+
invokeAndTransfer
|
|
1197
|
+
} = EditorWorker;
|
|
1198
|
+
|
|
1199
|
+
// TODO add tests for this
|
|
1200
|
+
const activateByEvent = async event => {
|
|
1201
|
+
// @ts-ignore
|
|
1202
|
+
await invoke$1('ActivateByEvent.activateByEvent', event);
|
|
1203
|
+
};
|
|
1204
|
+
|
|
1205
|
+
const {
|
|
1206
|
+
invoke,
|
|
1207
|
+
set
|
|
1208
|
+
} = ExtensionHost;
|
|
1209
|
+
|
|
1210
|
+
const execute = async ({
|
|
1211
|
+
editorLanguageId,
|
|
1212
|
+
editorUid,
|
|
1213
|
+
args,
|
|
1214
|
+
event,
|
|
1215
|
+
method,
|
|
1216
|
+
noProviderFoundMessage,
|
|
1217
|
+
noProviderFoundResult = undefined
|
|
1218
|
+
}) => {
|
|
1219
|
+
const fullEvent = `${event}:${editorLanguageId}`;
|
|
1220
|
+
await activateByEvent(fullEvent);
|
|
1221
|
+
const result = await invoke(method, editorUid, ...args);
|
|
1222
|
+
return result;
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
const executeCompletionProvider = async (editorUid, editorLanguageId, offset) => {
|
|
1226
|
+
return execute({
|
|
1227
|
+
editorUid,
|
|
1228
|
+
editorLanguageId,
|
|
1229
|
+
event: OnCompletion,
|
|
1230
|
+
method: CompletionExecute,
|
|
1231
|
+
args: [offset],
|
|
1232
|
+
noProviderFoundMessage: 'no completion provider found',
|
|
1233
|
+
noProviderFoundResult: []});
|
|
1234
|
+
};
|
|
1235
|
+
|
|
1236
|
+
const getOffsetAtCursor = editorUid => {
|
|
1237
|
+
// TODO ask editor worker
|
|
1238
|
+
return 0;
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1241
|
+
// TODO possible to do this with events/state machine instead of promises -> enables canceling operations / concurrent calls
|
|
1242
|
+
const getCompletions = async (editorUid, editorLanguageId) => {
|
|
1243
|
+
const offset = getOffsetAtCursor();
|
|
1244
|
+
const completions = await executeCompletionProvider(editorUid, editorLanguageId, offset);
|
|
1245
|
+
return completions;
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1248
|
+
const select = async (state, completionItem) => {
|
|
1249
|
+
// TODO ask editor worker to apply changes and close completion widget
|
|
1250
|
+
// const changes = await getEdits(state, completionItem)
|
|
1251
|
+
// TODO ask editor worker to remove widget
|
|
1252
|
+
// const index = state.widgets
|
|
1253
|
+
// .indexOf
|
|
1254
|
+
// // ViewletModuleId.EditorCompletion
|
|
1255
|
+
// ()
|
|
1256
|
+
// if (index !== -1) {
|
|
1257
|
+
// state.widgets.splice(index, 1)
|
|
1258
|
+
// state.completionState = EditorCompletionState.None
|
|
1259
|
+
// state.completionUid = 0
|
|
1260
|
+
// }
|
|
1261
|
+
// // TODO dispose completion widget
|
|
1262
|
+
// // TODO apply edit in editor worker instead of asking renderer worker
|
|
1263
|
+
// // await RendererWorker.invoke('Viewlet.dispose', state.uid)
|
|
1264
|
+
// const { widgets } = state
|
|
1265
|
+
// const newWidgets = RemoveEditorWidget.removeEditorWidget(widgets, WidgetId.Completion)
|
|
1266
|
+
// const intermediateEditor = await EditorCommandApplyEdit.applyEdit(state, changes)
|
|
1267
|
+
return {
|
|
1268
|
+
...state
|
|
1269
|
+
};
|
|
1270
|
+
};
|
|
1271
|
+
const selectIndex = async (state, index) => {
|
|
1272
|
+
const {
|
|
1273
|
+
items
|
|
1274
|
+
} = state;
|
|
1275
|
+
if (index === -1) {
|
|
1276
|
+
return state;
|
|
1277
|
+
}
|
|
1278
|
+
if (index > items.length) {
|
|
1279
|
+
throw new Error('index too large');
|
|
1280
|
+
}
|
|
1281
|
+
return select(state);
|
|
1282
|
+
};
|
|
1283
|
+
|
|
1284
|
+
const selectCurrent = state => {
|
|
1285
|
+
const {
|
|
1286
|
+
focusedIndex
|
|
1287
|
+
} = state;
|
|
1288
|
+
return selectIndex(state, focusedIndex);
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1094
1291
|
const commandIds = ['handleSliderPointerDown', 'handleSliderPointerMove', 'initialize'];
|
|
1095
1292
|
|
|
1096
1293
|
const getCommandIds = () => {
|
|
1097
1294
|
return commandIds;
|
|
1098
1295
|
};
|
|
1099
1296
|
|
|
1297
|
+
const Enter = 3;
|
|
1298
|
+
const Space$1 = 9;
|
|
1299
|
+
const End = 255;
|
|
1300
|
+
const Home = 12;
|
|
1301
|
+
const UpArrow = 14;
|
|
1302
|
+
const DownArrow = 16;
|
|
1303
|
+
|
|
1304
|
+
const CtrlCmd = 1 << 11 >>> 0;
|
|
1305
|
+
|
|
1306
|
+
const FocusEditorCompletions = 9;
|
|
1307
|
+
const FocusEditorRename = 11;
|
|
1308
|
+
|
|
1309
|
+
const Completion = 3;
|
|
1310
|
+
|
|
1311
|
+
const getCommand = shortId => {
|
|
1312
|
+
return {
|
|
1313
|
+
command: 'Editor.executeWidgetCommand',
|
|
1314
|
+
args: ['Completions', `Completions.${shortId}`, 0, Completion]
|
|
1315
|
+
};
|
|
1316
|
+
};
|
|
1317
|
+
const getKeyBindings = () => {
|
|
1318
|
+
return [{
|
|
1319
|
+
key: DownArrow,
|
|
1320
|
+
...getCommand('focusNext'),
|
|
1321
|
+
when: FocusEditorCompletions
|
|
1322
|
+
}, {
|
|
1323
|
+
key: UpArrow,
|
|
1324
|
+
...getCommand('focusPrevious'),
|
|
1325
|
+
when: FocusEditorCompletions
|
|
1326
|
+
}, {
|
|
1327
|
+
key: Enter,
|
|
1328
|
+
...getCommand('selectCurrent'),
|
|
1329
|
+
when: FocusEditorCompletions
|
|
1330
|
+
}, {
|
|
1331
|
+
key: End,
|
|
1332
|
+
...getCommand('focusLast'),
|
|
1333
|
+
when: FocusEditorCompletions
|
|
1334
|
+
}, {
|
|
1335
|
+
key: Home,
|
|
1336
|
+
...getCommand('focusFirst'),
|
|
1337
|
+
when: FocusEditorCompletions
|
|
1338
|
+
}, {
|
|
1339
|
+
key: CtrlCmd | Space$1,
|
|
1340
|
+
...getCommand('toggleDetails'),
|
|
1341
|
+
when: FocusEditorCompletions
|
|
1342
|
+
}];
|
|
1343
|
+
};
|
|
1344
|
+
|
|
1100
1345
|
const Diagonal = 1;
|
|
1101
1346
|
const Left = 2;
|
|
1102
1347
|
|
|
@@ -1304,63 +1549,40 @@ const getListHeight = (itemsLength, itemHeight, maxHeight) => {
|
|
|
1304
1549
|
return Math.min(totalHeight, maxHeight);
|
|
1305
1550
|
};
|
|
1306
1551
|
|
|
1307
|
-
const
|
|
1308
|
-
|
|
1309
|
-
rpcs[id] = rpc;
|
|
1310
|
-
};
|
|
1311
|
-
const get = id => {
|
|
1312
|
-
return rpcs[id];
|
|
1552
|
+
const getWordAtOffset = async editorUid => {
|
|
1553
|
+
return invoke$1('Editor.getWordAtOffset2', editorUid);
|
|
1313
1554
|
};
|
|
1314
1555
|
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1556
|
+
const handleEditorDeleteLeft = async state => {
|
|
1557
|
+
const {
|
|
1558
|
+
unfilteredItems,
|
|
1559
|
+
itemHeight,
|
|
1560
|
+
maxHeight,
|
|
1561
|
+
editorUid
|
|
1562
|
+
} = state;
|
|
1563
|
+
const x = 0; // TODO
|
|
1564
|
+
// @ts-ignore
|
|
1565
|
+
const y = 0; // TODP
|
|
1566
|
+
const wordAtOffset = await getWordAtOffset(editorUid);
|
|
1567
|
+
if (!wordAtOffset) {
|
|
1568
|
+
return {
|
|
1569
|
+
...state,
|
|
1570
|
+
disposed: true
|
|
1571
|
+
};
|
|
1572
|
+
}
|
|
1573
|
+
const items = filterCompletionItems(unfilteredItems, wordAtOffset);
|
|
1574
|
+
const newMaxLineY = Math.min(items.length, 8);
|
|
1575
|
+
const height = getListHeight(items.length, itemHeight, maxHeight);
|
|
1318
1576
|
return {
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
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
|
-
}
|
|
1577
|
+
...state,
|
|
1578
|
+
items,
|
|
1579
|
+
x,
|
|
1580
|
+
y,
|
|
1581
|
+
maxLineY: newMaxLineY,
|
|
1582
|
+
leadingWord: wordAtOffset,
|
|
1583
|
+
height
|
|
1334
1584
|
};
|
|
1335
1585
|
};
|
|
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
1586
|
|
|
1365
1587
|
const getPositionAtCursor = async parentUid => {
|
|
1366
1588
|
const position = await invoke$1('Editor.getPositionAtCursor', parentUid);
|
|
@@ -1368,7 +1590,6 @@ const getPositionAtCursor = async parentUid => {
|
|
|
1368
1590
|
};
|
|
1369
1591
|
|
|
1370
1592
|
const getWordBefore = async (editorUid, rowIndex, columnIndex) => {
|
|
1371
|
-
// @ts-ignore
|
|
1372
1593
|
return invoke$1('Editor.getWordBefore2', editorUid, rowIndex, columnIndex);
|
|
1373
1594
|
};
|
|
1374
1595
|
|
|
@@ -1404,6 +1625,52 @@ const handleEditorType = async state => {
|
|
|
1404
1625
|
};
|
|
1405
1626
|
};
|
|
1406
1627
|
|
|
1628
|
+
const clamp = (num, min, max) => {
|
|
1629
|
+
number(num);
|
|
1630
|
+
number(min);
|
|
1631
|
+
number(max);
|
|
1632
|
+
return Math.min(Math.max(num, min), max);
|
|
1633
|
+
};
|
|
1634
|
+
|
|
1635
|
+
// TODO optimize this function to return the minimum number
|
|
1636
|
+
// of visible items needed, e.g. when not scrolled 5 items with
|
|
1637
|
+
// 20px fill 100px but when scrolled 6 items are needed
|
|
1638
|
+
const getNumberOfVisibleItems = (listHeight, itemHeight) => {
|
|
1639
|
+
return Math.ceil(listHeight / itemHeight) + 1;
|
|
1640
|
+
};
|
|
1641
|
+
|
|
1642
|
+
const setDeltaY = (state, value) => {
|
|
1643
|
+
object(state);
|
|
1644
|
+
number(value);
|
|
1645
|
+
const {
|
|
1646
|
+
itemHeight,
|
|
1647
|
+
finalDeltaY,
|
|
1648
|
+
deltaY,
|
|
1649
|
+
height,
|
|
1650
|
+
headerHeight
|
|
1651
|
+
} = state;
|
|
1652
|
+
const listHeight = height - headerHeight;
|
|
1653
|
+
const newDeltaY = clamp(value, 0, finalDeltaY);
|
|
1654
|
+
if (deltaY === newDeltaY) {
|
|
1655
|
+
return state;
|
|
1656
|
+
}
|
|
1657
|
+
// TODO when it only moves by one px, extensions don't need to be rerendered, only negative margin
|
|
1658
|
+
const minLineY = Math.floor(newDeltaY / itemHeight);
|
|
1659
|
+
const maxLineY = minLineY + getNumberOfVisibleItems(listHeight, itemHeight);
|
|
1660
|
+
return {
|
|
1661
|
+
...state,
|
|
1662
|
+
deltaY: newDeltaY,
|
|
1663
|
+
minLineY,
|
|
1664
|
+
maxLineY
|
|
1665
|
+
};
|
|
1666
|
+
};
|
|
1667
|
+
|
|
1668
|
+
const handleWheel = (state, deltaMode, deltaY) => {
|
|
1669
|
+
number(deltaMode);
|
|
1670
|
+
number(deltaY);
|
|
1671
|
+
return setDeltaY(state, state.deltaY + deltaY);
|
|
1672
|
+
};
|
|
1673
|
+
|
|
1407
1674
|
const getPortTuple = () => {
|
|
1408
1675
|
const {
|
|
1409
1676
|
port1,
|
|
@@ -1441,75 +1708,17 @@ const createExtensionHostRpc = async () => {
|
|
|
1441
1708
|
}
|
|
1442
1709
|
};
|
|
1443
1710
|
|
|
1444
|
-
const {
|
|
1445
|
-
invoke,
|
|
1446
|
-
set
|
|
1447
|
-
} = ExtensionHost;
|
|
1448
|
-
|
|
1449
1711
|
const initialize = async () => {
|
|
1450
1712
|
const rpc = await createExtensionHostRpc();
|
|
1451
1713
|
set(rpc);
|
|
1452
1714
|
};
|
|
1453
1715
|
|
|
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
1716
|
const getFinalDeltaY = (height, itemHeight, itemsLength) => {
|
|
1503
1717
|
const contentHeight = itemsLength * itemHeight;
|
|
1504
1718
|
const finalDeltaY = Math.max(contentHeight - height, 0);
|
|
1505
1719
|
return finalDeltaY;
|
|
1506
1720
|
};
|
|
1507
1721
|
|
|
1508
|
-
const getWordAtOffset = async editorUid => {
|
|
1509
|
-
// @ts-ignore
|
|
1510
|
-
return invoke$1('Editor.getWordAtOffset2', editorUid);
|
|
1511
|
-
};
|
|
1512
|
-
|
|
1513
1722
|
const loadContent = async state => {
|
|
1514
1723
|
const {
|
|
1515
1724
|
itemHeight,
|
|
@@ -1546,12 +1755,14 @@ const loadContent = async state => {
|
|
|
1546
1755
|
// @ts-ignore
|
|
1547
1756
|
rowIndex,
|
|
1548
1757
|
columnIndex,
|
|
1549
|
-
width: 200
|
|
1758
|
+
width: 200,
|
|
1759
|
+
version: 1
|
|
1550
1760
|
};
|
|
1551
1761
|
};
|
|
1552
1762
|
|
|
1553
1763
|
const SetBounds = 'Viewlet.setBounds';
|
|
1554
1764
|
const SetDom2 = 'Viewlet.setDom2';
|
|
1765
|
+
const SetUid = 'Viewlet.setUid';
|
|
1555
1766
|
const SetEventListeners = 'Viewlet.registerEventListeners';
|
|
1556
1767
|
|
|
1557
1768
|
const renderBounds = (oldState, newState) => {
|
|
@@ -1585,34 +1796,22 @@ const renderEventListeners = state => {
|
|
|
1585
1796
|
return [SetEventListeners, uid, eventListeners];
|
|
1586
1797
|
};
|
|
1587
1798
|
|
|
1588
|
-
const
|
|
1589
|
-
|
|
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);
|
|
1799
|
+
const renderFocusContext = (oldState, newState) => {
|
|
1800
|
+
return [/* method */'Viewlet.setFocusContext', FocusEditorRename];
|
|
1598
1801
|
};
|
|
1599
1802
|
|
|
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
1803
|
const ColoredMaskIcon = 'ColoredMaskIcon';
|
|
1804
|
+
const EditorCompletion = 'EditorCompletion';
|
|
1610
1805
|
const EditorCompletionItem = 'EditorCompletionItem';
|
|
1611
1806
|
const EditorCompletionItemDeprecated = 'EditorCompletionItemDeprecated';
|
|
1612
1807
|
const EditorCompletionItemFocused = 'EditorCompletionItemFocused';
|
|
1613
1808
|
const EditorCompletionItemHighlight = 'EditorCompletionItemHighlight';
|
|
1614
1809
|
const FileIcon = 'FileIcon';
|
|
1615
1810
|
const Label = 'Label';
|
|
1811
|
+
const Viewlet = 'Viewlet';
|
|
1812
|
+
|
|
1813
|
+
const None = 'none';
|
|
1814
|
+
const Option = 'option';
|
|
1616
1815
|
|
|
1617
1816
|
const Div = 4;
|
|
1618
1817
|
const Span = 8;
|
|
@@ -1639,6 +1838,9 @@ const getIconDom = (fileIcon, symbolName) => {
|
|
|
1639
1838
|
};
|
|
1640
1839
|
};
|
|
1641
1840
|
|
|
1841
|
+
const mergeClassNames = (...classNames) => {
|
|
1842
|
+
return classNames.filter(Boolean).join(' ');
|
|
1843
|
+
};
|
|
1642
1844
|
const Text = 12;
|
|
1643
1845
|
const text = data => {
|
|
1644
1846
|
return {
|
|
@@ -1717,12 +1919,34 @@ const getCompletionItemVirtualDom = visibleItem => {
|
|
|
1717
1919
|
}, getIconDom(fileIcon, symbolName), ...getHighlightedLabelDom(label, highlights)];
|
|
1718
1920
|
};
|
|
1719
1921
|
|
|
1922
|
+
const emptyObject = {};
|
|
1923
|
+
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
1924
|
+
const i18nString = (key, placeholders = emptyObject) => {
|
|
1925
|
+
if (placeholders === emptyObject) {
|
|
1926
|
+
return key;
|
|
1927
|
+
}
|
|
1928
|
+
const replacer = (match, rest) => {
|
|
1929
|
+
return placeholders[rest];
|
|
1930
|
+
};
|
|
1931
|
+
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
1932
|
+
};
|
|
1933
|
+
|
|
1934
|
+
const NoResults = 'No Results';
|
|
1935
|
+
|
|
1936
|
+
const noResults = () => {
|
|
1937
|
+
return i18nString(NoResults);
|
|
1938
|
+
};
|
|
1939
|
+
|
|
1940
|
+
const getNoResultsVirtualDom = () => {
|
|
1941
|
+
return [{
|
|
1942
|
+
type: Div,
|
|
1943
|
+
childCount: 1
|
|
1944
|
+
}, text(noResults())];
|
|
1945
|
+
};
|
|
1946
|
+
|
|
1720
1947
|
const getCompletionItemsVirtualDom = visibleItems => {
|
|
1721
1948
|
if (visibleItems.length === 0) {
|
|
1722
|
-
return
|
|
1723
|
-
type: Div,
|
|
1724
|
-
childCount: 1
|
|
1725
|
-
}, text(noResults())];
|
|
1949
|
+
return getNoResultsVirtualDom();
|
|
1726
1950
|
}
|
|
1727
1951
|
const root = {
|
|
1728
1952
|
type: Div,
|
|
@@ -1732,6 +1956,24 @@ const getCompletionItemsVirtualDom = visibleItems => {
|
|
|
1732
1956
|
return dom;
|
|
1733
1957
|
};
|
|
1734
1958
|
|
|
1959
|
+
const getCompletionVirtualDom = visibleItems => {
|
|
1960
|
+
return [{
|
|
1961
|
+
type: Div,
|
|
1962
|
+
className: mergeClassNames(Viewlet, EditorCompletion),
|
|
1963
|
+
id: 'Completions',
|
|
1964
|
+
childCount: 1
|
|
1965
|
+
}, {
|
|
1966
|
+
type: Div,
|
|
1967
|
+
className: 'ListItems',
|
|
1968
|
+
role: 'listbox',
|
|
1969
|
+
ariaLabel: 'Suggest',
|
|
1970
|
+
childCount: 1
|
|
1971
|
+
}, ...getCompletionItemsVirtualDom(visibleItems)
|
|
1972
|
+
|
|
1973
|
+
// TODO render scrollbar
|
|
1974
|
+
];
|
|
1975
|
+
};
|
|
1976
|
+
|
|
1735
1977
|
const Property = 1;
|
|
1736
1978
|
const Value = 2;
|
|
1737
1979
|
const Function = 3;
|
|
@@ -1819,10 +2061,18 @@ const renderItems = (oldState, newState) => {
|
|
|
1819
2061
|
uid
|
|
1820
2062
|
} = newState;
|
|
1821
2063
|
const visibleItems = getVisibleItems(newState.items, newState.itemHeight, newState.leadingWord, newState.minLineY, newState.maxLineY, newState.focusedIndex);
|
|
1822
|
-
const dom =
|
|
2064
|
+
const dom = getCompletionVirtualDom(visibleItems);
|
|
1823
2065
|
return [SetDom2, uid, dom];
|
|
1824
2066
|
};
|
|
1825
2067
|
|
|
2068
|
+
const renderUid = (oldState, newState) => {
|
|
2069
|
+
const {
|
|
2070
|
+
uid,
|
|
2071
|
+
editorUid
|
|
2072
|
+
} = newState;
|
|
2073
|
+
return [SetUid, uid, editorUid];
|
|
2074
|
+
};
|
|
2075
|
+
|
|
1826
2076
|
const getRenderer = diffType => {
|
|
1827
2077
|
switch (diffType) {
|
|
1828
2078
|
case RenderContent:
|
|
@@ -1831,8 +2081,12 @@ const getRenderer = diffType => {
|
|
|
1831
2081
|
return renderBounds;
|
|
1832
2082
|
case RenderEventListeners:
|
|
1833
2083
|
return renderEventListeners;
|
|
2084
|
+
case RenderUid:
|
|
2085
|
+
return renderUid;
|
|
1834
2086
|
case RenderItems:
|
|
1835
2087
|
return renderItems;
|
|
2088
|
+
case RenderFocusContext:
|
|
2089
|
+
return renderFocusContext;
|
|
1836
2090
|
default:
|
|
1837
2091
|
throw new Error('unknown renderer');
|
|
1838
2092
|
}
|
|
@@ -1864,12 +2118,22 @@ const terminate = () => {
|
|
|
1864
2118
|
const commandMap = {
|
|
1865
2119
|
'Completions.create': create$1,
|
|
1866
2120
|
'Completions.diff2': diff2,
|
|
2121
|
+
'Completions.focusFirst': wrapCommand(focusFirst),
|
|
2122
|
+
'Completions.focusIndex': wrapCommand(focusIndex),
|
|
2123
|
+
'Completions.focusNext': wrapCommand(focusNext),
|
|
2124
|
+
'Completions.focusPrevious': wrapCommand(focusPrevious),
|
|
1867
2125
|
'Completions.getCommandIds': getCommandIds,
|
|
2126
|
+
'Completions.getKeyBindings': getKeyBindings,
|
|
2127
|
+
'Completions.handleEditorDeleteLeft': wrapCommand(handleEditorDeleteLeft),
|
|
2128
|
+
'Completions.handleEditorType': handleEditorType,
|
|
2129
|
+
'Completions.handleWheel': wrapCommand(handleWheel),
|
|
2130
|
+
'Completions.initialize': initialize,
|
|
1868
2131
|
'Completions.loadContent': wrapCommand(loadContent),
|
|
1869
2132
|
'Completions.render2': render2,
|
|
2133
|
+
'Completions.selectCurrent': wrapCommand(selectCurrent),
|
|
2134
|
+
'Completions.selectIndex': wrapCommand(selectIndex),
|
|
1870
2135
|
'Completions.terminate': terminate,
|
|
1871
|
-
'Completions.
|
|
1872
|
-
'Completions.handleEditorType': handleEditorType
|
|
2136
|
+
'Completions.openDetails': wrapCommand(openDetails)
|
|
1873
2137
|
};
|
|
1874
2138
|
|
|
1875
2139
|
const listen = async () => {
|