@lvce-editor/completion-worker 1.5.0 → 1.7.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.
@@ -94,6 +94,12 @@ const number = value => {
94
94
  throw new AssertionError('expected value to be of type number');
95
95
  }
96
96
  };
97
+ const string = value => {
98
+ const type = getType(value);
99
+ if (type !== 'string') {
100
+ throw new AssertionError('expected value to be of type string');
101
+ }
102
+ };
97
103
 
98
104
  const isMessagePort = value => {
99
105
  return value && value instanceof MessagePort;
@@ -1023,7 +1029,8 @@ const create$2 = () => {
1023
1029
  const {
1024
1030
  get: get$1,
1025
1031
  set: set$2,
1026
- wrapCommand
1032
+ wrapCommand,
1033
+ dispose: dispose$1
1027
1034
  } = create$2();
1028
1035
 
1029
1036
  const create$1 = (uid, x, y, width, height, editorUid, editorLanguageId) => {
@@ -1102,6 +1109,10 @@ const diff2 = uid => {
1102
1109
  return diffResult;
1103
1110
  };
1104
1111
 
1112
+ const dispose = uid => {
1113
+ dispose$1(uid);
1114
+ };
1115
+
1105
1116
  const focusIndex = (state, index) => {
1106
1117
  const newState = {
1107
1118
  ...state,
@@ -1134,10 +1145,6 @@ const openDetails = async state => {
1134
1145
  return state;
1135
1146
  };
1136
1147
 
1137
- const OnCompletion = 'onCompletion';
1138
-
1139
- const CompletionExecute = 'ExtensionHostCompletion.execute';
1140
-
1141
1148
  const rpcs = Object.create(null);
1142
1149
  const set$a = (id, rpc) => {
1143
1150
  rpcs[id] = rpc;
@@ -1196,6 +1203,11 @@ const {
1196
1203
  invokeAndTransfer
1197
1204
  } = EditorWorker;
1198
1205
 
1206
+ const OnCompletion = 'onCompletion';
1207
+
1208
+ const CompletionExecute = 'ExtensionHostCompletion.execute';
1209
+ const CompletionResolveExecute = 'ExtensionHostCompletion.executeResolve';
1210
+
1199
1211
  // TODO add tests for this
1200
1212
  const activateByEvent = async event => {
1201
1213
  // @ts-ignore
@@ -1232,6 +1244,15 @@ const executeCompletionProvider = async (editorUid, editorLanguageId, offset) =>
1232
1244
  noProviderFoundMessage: 'no completion provider found',
1233
1245
  noProviderFoundResult: []});
1234
1246
  };
1247
+ const executeResolveCompletionItem = async (editorUid, offset, name, completionItem) => {
1248
+ return execute({
1249
+ editorUid,
1250
+ event: OnCompletion,
1251
+ method: CompletionResolveExecute,
1252
+ args: [offset, name, completionItem],
1253
+ noProviderFoundMessage: 'no completion provider found',
1254
+ noProviderFoundResult: []});
1255
+ };
1235
1256
 
1236
1257
  const getOffsetAtCursor = editorUid => {
1237
1258
  // TODO ask editor worker
@@ -1245,29 +1266,102 @@ const getCompletions = async (editorUid, editorLanguageId) => {
1245
1266
  return completions;
1246
1267
  };
1247
1268
 
1269
+ // TODO don't send unnecessary parts of completion item like matches
1270
+ const resolveCompletion = async (editorUid, name, completionItem) => {
1271
+ try {
1272
+ string(name);
1273
+ object(completionItem);
1274
+ const offset = getOffsetAtCursor(editorUid);
1275
+ const resolvedCompletionItem = await executeResolveCompletionItem(editorUid, offset, name, completionItem);
1276
+ return resolvedCompletionItem;
1277
+ } catch {
1278
+ return undefined;
1279
+ }
1280
+ };
1281
+
1282
+ const getSelectionPairs = (selections, i) => {
1283
+ const first = selections[i];
1284
+ const second = selections[i + 1];
1285
+ const third = selections[i + 2];
1286
+ const fourth = selections[i + 3];
1287
+ if (first > third || first === third && second >= fourth) {
1288
+ return [third, fourth, first, second, 1];
1289
+ }
1290
+ return [first, second, third, fourth, 0];
1291
+ };
1292
+
1293
+ const getSelectionText = (lines, range) => {
1294
+ const startRowIndex = range.start.rowIndex;
1295
+ const startColumnIndex = range.start.columnIndex;
1296
+ const endRowIndex = Math.min(range.end.rowIndex, lines.length - 1);
1297
+ const endColumnIndex = range.end.columnIndex;
1298
+ if (startRowIndex === endRowIndex) {
1299
+ return [lines[startRowIndex].slice(startColumnIndex, endColumnIndex)];
1300
+ }
1301
+ const selectedLines = [lines[startRowIndex].slice(startColumnIndex), ...lines.slice(startRowIndex + 1, endRowIndex), lines[endRowIndex].slice(0, endColumnIndex)];
1302
+ return selectedLines;
1303
+ };
1304
+
1305
+ // TODO add more exact types
1306
+ const replaceRange = (lines, ranges, replacement, origin) => {
1307
+ const changes = [];
1308
+ const rangesLength = ranges.length;
1309
+ for (let i = 0; i < rangesLength; i += 4) {
1310
+ const [selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn] = getSelectionPairs(ranges, i);
1311
+ const start = {
1312
+ rowIndex: selectionStartRow,
1313
+ columnIndex: selectionStartColumn
1314
+ };
1315
+ const end = {
1316
+ rowIndex: selectionEndRow,
1317
+ columnIndex: selectionEndColumn
1318
+ };
1319
+ const selection = {
1320
+ start,
1321
+ end
1322
+ };
1323
+ changes.push({
1324
+ start: start,
1325
+ end: end,
1326
+ inserted: replacement,
1327
+ deleted: getSelectionText(lines, selection),
1328
+ origin
1329
+ });
1330
+ }
1331
+ return changes;
1332
+ };
1333
+
1334
+ const getEdits = async (editorUid, leadingWord, completionItem) => {
1335
+ const word = completionItem.label;
1336
+ const resolvedItem = await resolveCompletion(editorUid, word, completionItem);
1337
+ const inserted = resolvedItem ? resolvedItem.snippet : word;
1338
+ const lines = await invoke$1('Editor.getLines2', editorUid);
1339
+ const selections = await invoke$1('Editor.getSelections2', editorUid);
1340
+ const [startRowIndex, startColumnIndex] = selections;
1341
+ const leadingWordLength = leadingWord.length;
1342
+ const replaceRange$1 = new Uint32Array([startRowIndex, startColumnIndex - leadingWordLength, startRowIndex, startColumnIndex]);
1343
+ const changes = replaceRange(lines, replaceRange$1, [inserted], '');
1344
+ return changes;
1345
+ };
1346
+
1347
+ const Completion = 3;
1348
+
1248
1349
  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)
1350
+ const {
1351
+ editorUid,
1352
+ leadingWord
1353
+ } = state;
1354
+ const changes = await getEdits(editorUid, leadingWord, completionItem);
1355
+ // @ts-ignore
1356
+ await invoke$1('Editor.applyEdit2', editorUid, changes);
1357
+ // @ts-ignore
1358
+ await invoke$1('Editor.closeWidget2', editorUid, Completion, 'Completions');
1359
+ // TODO remove completion widget from editor
1267
1360
  return {
1268
1361
  ...state
1269
1362
  };
1270
1363
  };
1364
+
1271
1365
  const selectIndex = async (state, index) => {
1272
1366
  const {
1273
1367
  items
@@ -1278,7 +1372,9 @@ const selectIndex = async (state, index) => {
1278
1372
  if (index > items.length) {
1279
1373
  throw new Error('index too large');
1280
1374
  }
1281
- return select(state);
1375
+ const actualIndex = index;
1376
+ const completionItem = items[actualIndex];
1377
+ return select(state, completionItem);
1282
1378
  };
1283
1379
 
1284
1380
  const selectCurrent = state => {
@@ -1306,8 +1402,6 @@ const CtrlCmd = 1 << 11 >>> 0;
1306
1402
  const FocusEditorCompletions = 9;
1307
1403
  const FocusEditorRename = 11;
1308
1404
 
1309
- const Completion = 3;
1310
-
1311
1405
  const getCommand = shortId => {
1312
1406
  return {
1313
1407
  command: 'Editor.executeWidgetCommand',
@@ -2118,6 +2212,7 @@ const terminate = () => {
2118
2212
  const commandMap = {
2119
2213
  'Completions.create': create$1,
2120
2214
  'Completions.diff2': diff2,
2215
+ 'Completions.dispose': dispose,
2121
2216
  'Completions.focusFirst': wrapCommand(focusFirst),
2122
2217
  'Completions.focusIndex': wrapCommand(focusIndex),
2123
2218
  'Completions.focusNext': wrapCommand(focusNext),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/completion-worker",
3
- "version": "1.5.0",
3
+ "version": "1.7.0",
4
4
  "description": "Web Worker for the find widget in Lvce Editor",
5
5
  "repository": {
6
6
  "type": "git",