@lvce-editor/completion-worker 1.5.0 → 1.6.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 +110 -23
- package/package.json +1 -1
|
@@ -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;
|
|
@@ -1134,10 +1140,6 @@ const openDetails = async state => {
|
|
|
1134
1140
|
return state;
|
|
1135
1141
|
};
|
|
1136
1142
|
|
|
1137
|
-
const OnCompletion = 'onCompletion';
|
|
1138
|
-
|
|
1139
|
-
const CompletionExecute = 'ExtensionHostCompletion.execute';
|
|
1140
|
-
|
|
1141
1143
|
const rpcs = Object.create(null);
|
|
1142
1144
|
const set$a = (id, rpc) => {
|
|
1143
1145
|
rpcs[id] = rpc;
|
|
@@ -1196,6 +1198,11 @@ const {
|
|
|
1196
1198
|
invokeAndTransfer
|
|
1197
1199
|
} = EditorWorker;
|
|
1198
1200
|
|
|
1201
|
+
const OnCompletion = 'onCompletion';
|
|
1202
|
+
|
|
1203
|
+
const CompletionExecute = 'ExtensionHostCompletion.execute';
|
|
1204
|
+
const CompletionResolveExecute = 'ExtensionHostCompletion.executeResolve';
|
|
1205
|
+
|
|
1199
1206
|
// TODO add tests for this
|
|
1200
1207
|
const activateByEvent = async event => {
|
|
1201
1208
|
// @ts-ignore
|
|
@@ -1232,6 +1239,14 @@ const executeCompletionProvider = async (editorUid, editorLanguageId, offset) =>
|
|
|
1232
1239
|
noProviderFoundMessage: 'no completion provider found',
|
|
1233
1240
|
noProviderFoundResult: []});
|
|
1234
1241
|
};
|
|
1242
|
+
const executeResolveCompletionItem = async (editor, offset, name, completionItem) => {
|
|
1243
|
+
return execute({
|
|
1244
|
+
event: OnCompletion,
|
|
1245
|
+
method: CompletionResolveExecute,
|
|
1246
|
+
args: [offset, name, completionItem],
|
|
1247
|
+
noProviderFoundMessage: 'no completion provider found',
|
|
1248
|
+
noProviderFoundResult: []});
|
|
1249
|
+
};
|
|
1235
1250
|
|
|
1236
1251
|
const getOffsetAtCursor = editorUid => {
|
|
1237
1252
|
// TODO ask editor worker
|
|
@@ -1245,29 +1260,99 @@ const getCompletions = async (editorUid, editorLanguageId) => {
|
|
|
1245
1260
|
return completions;
|
|
1246
1261
|
};
|
|
1247
1262
|
|
|
1263
|
+
// TODO don't send unnecessary parts of completion item like matches
|
|
1264
|
+
const resolveCompletion = async (editorUid, name, completionItem) => {
|
|
1265
|
+
try {
|
|
1266
|
+
string(name);
|
|
1267
|
+
object(completionItem);
|
|
1268
|
+
const offset = getOffsetAtCursor(editorUid);
|
|
1269
|
+
// @ts-ignore
|
|
1270
|
+
const resolvedCompletionItem = await executeResolveCompletionItem(editor, offset, name, completionItem);
|
|
1271
|
+
return resolvedCompletionItem;
|
|
1272
|
+
} catch {
|
|
1273
|
+
return undefined;
|
|
1274
|
+
}
|
|
1275
|
+
};
|
|
1276
|
+
|
|
1277
|
+
const getSelectionPairs = (selections, i) => {
|
|
1278
|
+
const first = selections[i];
|
|
1279
|
+
const second = selections[i + 1];
|
|
1280
|
+
const third = selections[i + 2];
|
|
1281
|
+
const fourth = selections[i + 3];
|
|
1282
|
+
if (first > third || first === third && second >= fourth) {
|
|
1283
|
+
return [third, fourth, first, second, 1];
|
|
1284
|
+
}
|
|
1285
|
+
return [first, second, third, fourth, 0];
|
|
1286
|
+
};
|
|
1287
|
+
|
|
1288
|
+
const getSelectionText = (lines, range) => {
|
|
1289
|
+
const startRowIndex = range.start.rowIndex;
|
|
1290
|
+
const startColumnIndex = range.start.columnIndex;
|
|
1291
|
+
const endRowIndex = Math.min(range.end.rowIndex, lines.length - 1);
|
|
1292
|
+
const endColumnIndex = range.end.columnIndex;
|
|
1293
|
+
if (startRowIndex === endRowIndex) {
|
|
1294
|
+
return [lines[startRowIndex].slice(startColumnIndex, endColumnIndex)];
|
|
1295
|
+
}
|
|
1296
|
+
const selectedLines = [lines[startRowIndex].slice(startColumnIndex), ...lines.slice(startRowIndex + 1, endRowIndex), lines[endRowIndex].slice(0, endColumnIndex)];
|
|
1297
|
+
return selectedLines;
|
|
1298
|
+
};
|
|
1299
|
+
|
|
1300
|
+
// TODO add more exact types
|
|
1301
|
+
const replaceRange = (lines, ranges, replacement, origin) => {
|
|
1302
|
+
const changes = [];
|
|
1303
|
+
const rangesLength = ranges.length;
|
|
1304
|
+
for (let i = 0; i < rangesLength; i += 4) {
|
|
1305
|
+
const [selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn] = getSelectionPairs(ranges, i);
|
|
1306
|
+
const start = {
|
|
1307
|
+
rowIndex: selectionStartRow,
|
|
1308
|
+
columnIndex: selectionStartColumn
|
|
1309
|
+
};
|
|
1310
|
+
const end = {
|
|
1311
|
+
rowIndex: selectionEndRow,
|
|
1312
|
+
columnIndex: selectionEndColumn
|
|
1313
|
+
};
|
|
1314
|
+
const selection = {
|
|
1315
|
+
start,
|
|
1316
|
+
end
|
|
1317
|
+
};
|
|
1318
|
+
changes.push({
|
|
1319
|
+
start: start,
|
|
1320
|
+
end: end,
|
|
1321
|
+
inserted: replacement,
|
|
1322
|
+
deleted: getSelectionText(lines, selection),
|
|
1323
|
+
origin
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
return changes;
|
|
1327
|
+
};
|
|
1328
|
+
|
|
1329
|
+
const getEdits = async (editorUid, leadingWord, completionItem) => {
|
|
1330
|
+
const word = completionItem.label;
|
|
1331
|
+
const resolvedItem = await resolveCompletion(editorUid, word, completionItem);
|
|
1332
|
+
const inserted = resolvedItem ? resolvedItem.snippet : word;
|
|
1333
|
+
const lines = await invoke$1('Editor.getLines2', editorUid);
|
|
1334
|
+
const selections = await invoke$1('Editor.getSelections2', editorUid);
|
|
1335
|
+
const [startRowIndex, startColumnIndex] = selections;
|
|
1336
|
+
const leadingWordLength = leadingWord.length;
|
|
1337
|
+
const replaceRange$1 = new Uint32Array([startRowIndex, startColumnIndex - leadingWordLength, startRowIndex, startColumnIndex]);
|
|
1338
|
+
const changes = replaceRange(lines, replaceRange$1, [inserted], '');
|
|
1339
|
+
return changes;
|
|
1340
|
+
};
|
|
1341
|
+
|
|
1248
1342
|
const select = async (state, completionItem) => {
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
//
|
|
1255
|
-
|
|
1256
|
-
//
|
|
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)
|
|
1343
|
+
const {
|
|
1344
|
+
editorUid,
|
|
1345
|
+
leadingWord
|
|
1346
|
+
} = state;
|
|
1347
|
+
const changes = await getEdits(editorUid, leadingWord, completionItem);
|
|
1348
|
+
// @ts-ignore
|
|
1349
|
+
await invoke$1('Editor.applyEdit2', editorUid, changes);
|
|
1350
|
+
// TODO remove completion widget from editor
|
|
1267
1351
|
return {
|
|
1268
1352
|
...state
|
|
1269
1353
|
};
|
|
1270
1354
|
};
|
|
1355
|
+
|
|
1271
1356
|
const selectIndex = async (state, index) => {
|
|
1272
1357
|
const {
|
|
1273
1358
|
items
|
|
@@ -1278,7 +1363,9 @@ const selectIndex = async (state, index) => {
|
|
|
1278
1363
|
if (index > items.length) {
|
|
1279
1364
|
throw new Error('index too large');
|
|
1280
1365
|
}
|
|
1281
|
-
|
|
1366
|
+
const actualIndex = index;
|
|
1367
|
+
const completionItem = items[actualIndex];
|
|
1368
|
+
return select(state, completionItem);
|
|
1282
1369
|
};
|
|
1283
1370
|
|
|
1284
1371
|
const selectCurrent = state => {
|