@lvce-editor/editor-worker 2.2.0 → 2.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/README.md +4 -0
- package/dist/editorWorkerMain.js +1403 -1530
- package/package.json +1 -1
package/dist/editorWorkerMain.js
CHANGED
|
@@ -238,1096 +238,131 @@ const IndentMore = 'indentMore';
|
|
|
238
238
|
const InsertLineBreak = 'insertLineBreak';
|
|
239
239
|
const ToggleBlockComment = 'toggleBlockComment';
|
|
240
240
|
|
|
241
|
-
const
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
const Space = ' ';
|
|
245
|
-
const Tab = '\t';
|
|
246
|
-
const Underline = '_';
|
|
247
|
-
const T = 't';
|
|
248
|
-
|
|
249
|
-
// @ts-ignore
|
|
250
|
-
const getFontString = (fontWeight, fontSize, fontFamily) => {
|
|
251
|
-
return `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
241
|
+
const modules = Object.create(null);
|
|
242
|
+
const register = (id, value) => {
|
|
243
|
+
modules[id] = value;
|
|
252
244
|
};
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
return `${letterSpacing}px`;
|
|
245
|
+
const get$7 = id => {
|
|
246
|
+
return modules[id];
|
|
256
247
|
};
|
|
257
248
|
|
|
258
|
-
const
|
|
259
|
-
|
|
249
|
+
const getModule$2 = id => {
|
|
250
|
+
return get$7(id);
|
|
260
251
|
};
|
|
261
252
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
253
|
+
const applyWidgetChange = (editor, widget, changes) => {
|
|
254
|
+
const module = getModule$2(widget.id);
|
|
255
|
+
if (changes.length === 1 && changes[0].origin === EditorType && module.handleEditorType) {
|
|
256
|
+
const newState = module.handleEditorType(editor, widget.newState);
|
|
257
|
+
return {
|
|
258
|
+
...widget,
|
|
259
|
+
newState
|
|
260
|
+
};
|
|
269
261
|
}
|
|
270
|
-
|
|
271
|
-
|
|
262
|
+
if (changes.length === 1 && changes[0].origin === DeleteLeft && module.handleEditorDeleteLeft) {
|
|
263
|
+
const newState = module.handleEditorDeleteLeft(editor, widget.newState);
|
|
264
|
+
return {
|
|
265
|
+
...widget,
|
|
266
|
+
newState
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return widget;
|
|
272
270
|
};
|
|
273
271
|
|
|
274
|
-
const
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
throw new Error('Failed to get canvas context 2d');
|
|
272
|
+
const applyWidgetChanges = (editor, changes) => {
|
|
273
|
+
const widgets = editor.widgets || [];
|
|
274
|
+
if (widgets.length === 0) {
|
|
275
|
+
return widgets;
|
|
279
276
|
}
|
|
280
|
-
|
|
277
|
+
const newWidgets = [];
|
|
278
|
+
for (const widget of widgets) {
|
|
279
|
+
const newWidget = applyWidgetChange(editor, widget, changes);
|
|
280
|
+
if (newWidget.newState) {
|
|
281
|
+
newWidgets.push(newWidget);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return newWidgets;
|
|
281
285
|
};
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
286
|
+
|
|
287
|
+
const getScrollBarOffset = (delta, finalDelta, size, scrollBarSize) => {
|
|
288
|
+
const scrollBarOffset = delta / finalDelta * (size - scrollBarSize);
|
|
289
|
+
return scrollBarOffset;
|
|
285
290
|
};
|
|
291
|
+
const getScrollBarY = getScrollBarOffset;
|
|
286
292
|
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
number$1(fontSize);
|
|
291
|
-
string(fontFamily);
|
|
292
|
-
boolean(isMonoSpaceFont);
|
|
293
|
-
number$1(charWidth);
|
|
294
|
-
if (isMonoSpaceFont) {
|
|
295
|
-
return text.length * charWidth;
|
|
296
|
-
}
|
|
297
|
-
if (typeof letterSpacing !== 'number') {
|
|
298
|
-
throw new TypeError('letterSpacing must be of type number');
|
|
293
|
+
const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
|
|
294
|
+
if (size >= contentSize) {
|
|
295
|
+
return 0;
|
|
299
296
|
}
|
|
300
|
-
|
|
301
|
-
const fontString = getFontString(fontWeight, fontSize, fontFamily);
|
|
302
|
-
const ctx = getContext();
|
|
303
|
-
// @ts-ignore
|
|
304
|
-
ctx.letterSpacing = letterSpacingString;
|
|
305
|
-
// @ts-ignore
|
|
306
|
-
ctx.font = fontString;
|
|
307
|
-
// @ts-ignore
|
|
308
|
-
const metrics = ctx.measureText(text);
|
|
309
|
-
const width = metrics.width;
|
|
310
|
-
return width;
|
|
297
|
+
return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
|
|
311
298
|
};
|
|
312
299
|
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
// @ts-ignore
|
|
317
|
-
guess,
|
|
318
|
-
// @ts-ignore
|
|
319
|
-
averageCharWidth,
|
|
320
|
-
// @ts-ignore
|
|
321
|
-
eventX,
|
|
322
|
-
// @ts-ignore
|
|
323
|
-
fontWeight,
|
|
324
|
-
// @ts-ignore
|
|
325
|
-
fontSize,
|
|
326
|
-
// @ts-ignore
|
|
327
|
-
fontFamily,
|
|
328
|
-
// @ts-ignore
|
|
329
|
-
letterSpacing,
|
|
330
|
-
// @ts-ignore
|
|
331
|
-
isMonospaceFont,
|
|
332
|
-
// @ts-ignore
|
|
333
|
-
charWidth) => {
|
|
334
|
-
for (let i = guess; i < line.length; i++) {
|
|
335
|
-
const width = measureTextWidth(line.slice(0, i), fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
336
|
-
if (eventX - width < averageCharWidth / 2) {
|
|
337
|
-
return i;
|
|
338
|
-
}
|
|
300
|
+
const getScrollBarWidth = (width, longestLineWidth) => {
|
|
301
|
+
if (width > longestLineWidth) {
|
|
302
|
+
return 0;
|
|
339
303
|
}
|
|
340
|
-
return
|
|
304
|
+
return width ** 2 / longestLineWidth;
|
|
341
305
|
};
|
|
342
306
|
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
307
|
+
const getNewDeltaPercent = (height, scrollBarHeight, relativeY) => {
|
|
308
|
+
const halfScrollBarHeight = scrollBarHeight / 2;
|
|
309
|
+
if (relativeY <= halfScrollBarHeight) {
|
|
310
|
+
// clicked at top
|
|
311
|
+
return {
|
|
312
|
+
percent: 0,
|
|
313
|
+
handleOffset: relativeY
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
if (relativeY <= height - halfScrollBarHeight) {
|
|
317
|
+
// clicked in middle
|
|
318
|
+
return {
|
|
319
|
+
percent: (relativeY - halfScrollBarHeight) / (height - scrollBarHeight),
|
|
320
|
+
handleOffset: halfScrollBarHeight
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
// clicked at bottom
|
|
349
324
|
return {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
return segments.containing(index);
|
|
353
|
-
},
|
|
354
|
-
visualIndex(line, index) {
|
|
355
|
-
const segments = segmenter.segment(line);
|
|
356
|
-
let currentVisualIndex = 0;
|
|
357
|
-
for (const segment of segments) {
|
|
358
|
-
if (segment.index >= index) {
|
|
359
|
-
return currentVisualIndex;
|
|
360
|
-
}
|
|
361
|
-
currentVisualIndex++;
|
|
362
|
-
}
|
|
363
|
-
return currentVisualIndex;
|
|
364
|
-
},
|
|
365
|
-
modelIndex(line, visualIndex) {
|
|
366
|
-
const segments = segmenter.segment(line);
|
|
367
|
-
let currentVisualIndex = 0;
|
|
368
|
-
for (const segment of segments) {
|
|
369
|
-
if (currentVisualIndex >= visualIndex) {
|
|
370
|
-
return segment.index;
|
|
371
|
-
}
|
|
372
|
-
currentVisualIndex++;
|
|
373
|
-
}
|
|
374
|
-
return line.length;
|
|
375
|
-
},
|
|
376
|
-
getSegments(line) {
|
|
377
|
-
return segmenter.segment(line);
|
|
378
|
-
}
|
|
325
|
+
percent: 1,
|
|
326
|
+
handleOffset: scrollBarHeight - height + relativeY
|
|
379
327
|
};
|
|
380
328
|
};
|
|
381
329
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const segments = segmenter.getSegments(line);
|
|
386
|
-
const isMonospaceFont = false;
|
|
387
|
-
const charWidth = 0;
|
|
388
|
-
for (const segment of segments) {
|
|
389
|
-
const width = measureTextWidth(line.slice(0, segment.index), fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
390
|
-
if (eventX - width < averageCharWidth) {
|
|
391
|
-
return segment.index;
|
|
392
|
-
}
|
|
330
|
+
const splitLines$2 = lines => {
|
|
331
|
+
if (!lines) {
|
|
332
|
+
return [];
|
|
393
333
|
}
|
|
394
|
-
return
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
const RE_ASCII = /^[\p{ASCII}]*$/u;
|
|
398
|
-
const isAscii = line => {
|
|
399
|
-
return RE_ASCII.test(line);
|
|
334
|
+
return lines.split('\n');
|
|
400
335
|
};
|
|
401
336
|
|
|
402
|
-
|
|
403
|
-
if (normalize) {
|
|
404
|
-
return text.replaceAll(Tab, Space.repeat(tabSize));
|
|
405
|
-
}
|
|
406
|
-
return text;
|
|
407
|
-
};
|
|
408
|
-
const shouldNormalizeText = text => {
|
|
409
|
-
return text.includes(Tab);
|
|
410
|
-
};
|
|
337
|
+
// based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/common/arrays.ts#L625 (License MIT)
|
|
411
338
|
|
|
412
339
|
// @ts-ignore
|
|
413
|
-
const
|
|
414
|
-
const
|
|
415
|
-
|
|
340
|
+
const insertInto = (array, start, newItems) => {
|
|
341
|
+
const originalLength = array.length;
|
|
342
|
+
const newItemsLength = newItems.length;
|
|
343
|
+
array.length = originalLength + newItemsLength;
|
|
344
|
+
// Move the items after the start index, start from the end so that we don't overwrite any value.
|
|
345
|
+
for (let i = originalLength - 1; i >= start; i--) {
|
|
346
|
+
array[i + newItemsLength] = array[i];
|
|
347
|
+
}
|
|
348
|
+
for (let i = 0; i < newItemsLength; i++) {
|
|
349
|
+
array[i + start] = newItems[i];
|
|
350
|
+
}
|
|
416
351
|
};
|
|
417
352
|
|
|
353
|
+
/**
|
|
354
|
+
* Alternative to the native Array.splice method, it
|
|
355
|
+
* can only support limited number of items due to the maximum call stack size limit.
|
|
356
|
+
*/
|
|
418
357
|
// @ts-ignore
|
|
419
|
-
const
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
normalizedGuess -= tabSize - 1;
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
return normalizedGuess;
|
|
358
|
+
const spliceLargeArray = (array, start, deleteCount, newItems) => {
|
|
359
|
+
const result = array.splice(start, deleteCount);
|
|
360
|
+
insertInto(array, start, newItems);
|
|
361
|
+
return result;
|
|
427
362
|
};
|
|
428
363
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
string(line);
|
|
432
|
-
number$1(fontWeight);
|
|
433
|
-
number$1(fontSize);
|
|
434
|
-
string(fontFamily);
|
|
435
|
-
number$1(letterSpacing);
|
|
436
|
-
boolean(isMonospaceFont);
|
|
437
|
-
number$1(charWidth);
|
|
438
|
-
number$1(tabSize);
|
|
439
|
-
number$1(eventX);
|
|
440
|
-
// Assert.greaterZero(charWidth)
|
|
441
|
-
const guess = guessOffset(eventX, charWidth);
|
|
442
|
-
const normalize = shouldNormalizeText(line);
|
|
443
|
-
const normalizedGuess = normalizeGuess(line, guess, tabSize);
|
|
444
|
-
const text = line.slice(0, normalizedGuess);
|
|
445
|
-
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
446
|
-
const actual = measureTextWidth(normalizedText, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
447
|
-
const isAscii$1 = isAscii(line);
|
|
448
|
-
if (isAscii$1) {
|
|
449
|
-
if (Math.abs(eventX - actual) < charWidth / 2) {
|
|
450
|
-
return normalizedGuess;
|
|
451
|
-
}
|
|
452
|
-
return getAccurateColumnIndexAscii(line, normalizedGuess, charWidth, eventX, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
453
|
-
}
|
|
454
|
-
return getAccurateColumnIndexUnicode(line, normalizedGuess, charWidth, eventX, fontWeight, fontSize, fontFamily, letterSpacing);
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
// @ts-ignore
|
|
458
|
-
const at = (editor, eventX, eventY) => {
|
|
459
|
-
object(editor);
|
|
460
|
-
number$1(eventX);
|
|
461
|
-
number$1(eventY);
|
|
462
|
-
const {
|
|
463
|
-
y,
|
|
464
|
-
deltaY,
|
|
465
|
-
rowHeight,
|
|
466
|
-
fontSize,
|
|
467
|
-
fontWeight,
|
|
468
|
-
fontFamily,
|
|
469
|
-
letterSpacing,
|
|
470
|
-
lines,
|
|
471
|
-
tabSize,
|
|
472
|
-
differences,
|
|
473
|
-
isMonospaceFont,
|
|
474
|
-
charWidth
|
|
475
|
-
} = editor;
|
|
476
|
-
const rowIndex = Math.floor((eventY - y + deltaY) / rowHeight);
|
|
477
|
-
if (rowIndex < 0) {
|
|
478
|
-
return {
|
|
479
|
-
rowIndex: 0,
|
|
480
|
-
columnIndex: 0
|
|
481
|
-
};
|
|
482
|
-
}
|
|
483
|
-
const clampedRowIndex = clamp(rowIndex, 0, lines.length - 1);
|
|
484
|
-
const line = lines[clampedRowIndex];
|
|
485
|
-
const columnIndex = getAccurateColumnIndex(line, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth, tabSize, eventX);
|
|
486
|
-
return {
|
|
487
|
-
rowIndex: clampedRowIndex,
|
|
488
|
-
columnIndex
|
|
489
|
-
};
|
|
490
|
-
};
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* @deprecated this doesn't work for variable width characters (unicode/emoji).
|
|
494
|
-
* Use position computation in renderer process instead
|
|
495
|
-
*
|
|
496
|
-
* @param {object} editor
|
|
497
|
-
* @param {number} rowIndex
|
|
498
|
-
* @param {number} columnIndex
|
|
499
|
-
* @returns
|
|
500
|
-
*/
|
|
501
|
-
// @ts-ignore
|
|
502
|
-
const x = (editor, rowIndex, columnIndex) => {
|
|
503
|
-
const {
|
|
504
|
-
columnWidth,
|
|
505
|
-
x
|
|
506
|
-
} = editor;
|
|
507
|
-
const offsetX = columnIndex * columnWidth + x;
|
|
508
|
-
return offsetX;
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
// @ts-ignore
|
|
512
|
-
const y = (editor, rowIndex) => {
|
|
513
|
-
const {
|
|
514
|
-
rowHeight,
|
|
515
|
-
y
|
|
516
|
-
} = editor;
|
|
517
|
-
const offsetY = (rowIndex + 1) * rowHeight + y;
|
|
518
|
-
return offsetY;
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
const emptyObject = {};
|
|
522
|
-
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
523
|
-
const i18nString = (key, placeholders = emptyObject) => {
|
|
524
|
-
if (placeholders === emptyObject) {
|
|
525
|
-
return key;
|
|
526
|
-
}
|
|
527
|
-
const replacer = (match, rest) => {
|
|
528
|
-
return placeholders[rest];
|
|
529
|
-
};
|
|
530
|
-
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
531
|
-
};
|
|
532
|
-
|
|
533
|
-
/**
|
|
534
|
-
* @enum {string}
|
|
535
|
-
*/
|
|
536
|
-
const UiStrings = {
|
|
537
|
-
OrganizeImports: 'Organize Imports',
|
|
538
|
-
Copy: 'Copy',
|
|
539
|
-
CopyLineDown: 'Copy Line Down',
|
|
540
|
-
CopyLineUp: 'Copy Line Up',
|
|
541
|
-
Cut: 'Cut',
|
|
542
|
-
DuplicateSelection: 'Duplicate Selection',
|
|
543
|
-
FindAllImplementations: 'Find All Implementations',
|
|
544
|
-
FindAllReferences: 'Find All References',
|
|
545
|
-
GoToDefinition: 'Go to Definition',
|
|
546
|
-
GoToTypeDefinition: 'Go to Type Definition',
|
|
547
|
-
MoveLineDown: 'Move Line Down',
|
|
548
|
-
MoveLineUp: 'Move Line Up',
|
|
549
|
-
NoDefinitionFound: 'No definition found',
|
|
550
|
-
NoDefinitionFoundFor: "No definition found for '{PH1}'",
|
|
551
|
-
NoTypeDefinitionFound: 'No type definition found',
|
|
552
|
-
NoTypeDefinitionFoundFor: "No type definition found for '{PH1}'",
|
|
553
|
-
Paste: 'Paste',
|
|
554
|
-
Redo: 'Redo',
|
|
555
|
-
SelectAll: 'Select All',
|
|
556
|
-
Separator: 'Separator',
|
|
557
|
-
ToggleBlockComment: 'Toggle Block Comment',
|
|
558
|
-
ToggleLineComment: 'Toggle Line Comment',
|
|
559
|
-
Undo: 'Undo',
|
|
560
|
-
FormatDocument: 'Format Document',
|
|
561
|
-
SourceActions: 'Source Actions',
|
|
562
|
-
EditorShowHover: 'Show Hover',
|
|
563
|
-
EditorFormatDocumentForced: 'Editor: Format Document (forced)',
|
|
564
|
-
EditorSelectNextOccurrence: 'Editor: Select Next Occurrence',
|
|
565
|
-
EditorSelectAllOccurrences: 'Editor: Select All Occurrences',
|
|
566
|
-
EditorGoToDefinition: 'Editor: Go To Definition',
|
|
567
|
-
EditorGoToTypeDefinition: 'Editor: Go To Type Definition',
|
|
568
|
-
EditorSelectInsideString: 'Editor: Select Inside String',
|
|
569
|
-
EditorIndent: 'Editor: Indent',
|
|
570
|
-
EditorUnindent: 'Editor: Unindent',
|
|
571
|
-
EditorSortLinesAscending: 'Editor: Sort Lines Ascending',
|
|
572
|
-
EditorToggleComment: 'Editor: Toggle Comment',
|
|
573
|
-
EditorSelectUp: 'Editor: Select Up',
|
|
574
|
-
EditorSelectDown: 'Editor: Select Down',
|
|
575
|
-
EditorToggleBlockComment: 'Editor: Toggle Block Comment',
|
|
576
|
-
EditorOpenColorPicker: 'Editor: Open Color Picker',
|
|
577
|
-
EditorCloseColorPicker: 'Editor: Close Color Picker',
|
|
578
|
-
EditorCopyLineDown: 'Editor: Copy Line Down',
|
|
579
|
-
EditorCopyLineUp: 'Editor: Copy Line Up',
|
|
580
|
-
Replace: 'replace',
|
|
581
|
-
NoResults: 'No Results'
|
|
582
|
-
};
|
|
583
|
-
const noDefinitionFound = () => {
|
|
584
|
-
return i18nString(UiStrings.NoDefinitionFound);
|
|
585
|
-
};
|
|
586
|
-
|
|
587
|
-
// @ts-ignore
|
|
588
|
-
const noDefinitionFoundFor = word => {
|
|
589
|
-
return i18nString(UiStrings.NoDefinitionFoundFor, {
|
|
590
|
-
PH1: word
|
|
591
|
-
});
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
// @ts-ignore
|
|
595
|
-
const noTypeDefinitionFoundFor = word => {
|
|
596
|
-
return i18nString(UiStrings.NoTypeDefinitionFoundFor, {
|
|
597
|
-
PH1: word
|
|
598
|
-
});
|
|
599
|
-
};
|
|
600
|
-
const noTypeDefinitionFound = () => {
|
|
601
|
-
return i18nString(UiStrings.NoTypeDefinitionFound);
|
|
602
|
-
};
|
|
603
|
-
const noResults = () => {
|
|
604
|
-
return i18nString(UiStrings.NoResults);
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
const None$1 = 'none';
|
|
608
|
-
const Option = 'option';
|
|
609
|
-
|
|
610
|
-
const getFileIconVirtualDom = icon => {
|
|
611
|
-
return {
|
|
612
|
-
type: Img,
|
|
613
|
-
className: FileIcon,
|
|
614
|
-
src: icon,
|
|
615
|
-
role: None$1,
|
|
616
|
-
childCount: 0
|
|
617
|
-
};
|
|
618
|
-
};
|
|
619
|
-
|
|
620
|
-
const getIconDom = (fileIcon, symbolName) => {
|
|
621
|
-
if (fileIcon) {
|
|
622
|
-
return getFileIconVirtualDom(fileIcon);
|
|
623
|
-
}
|
|
624
|
-
return {
|
|
625
|
-
type: Div,
|
|
626
|
-
className: `${ColoredMaskIcon} ${symbolName}`,
|
|
627
|
-
childCount: 0
|
|
628
|
-
};
|
|
629
|
-
};
|
|
630
|
-
|
|
631
|
-
const text = data => {
|
|
632
|
-
return {
|
|
633
|
-
type: Text,
|
|
634
|
-
text: data,
|
|
635
|
-
childCount: 0
|
|
636
|
-
};
|
|
637
|
-
};
|
|
638
|
-
|
|
639
|
-
const label1 = {
|
|
640
|
-
type: Div,
|
|
641
|
-
className: Label,
|
|
642
|
-
childCount: 1
|
|
643
|
-
};
|
|
644
|
-
const completionHighlight = {
|
|
645
|
-
type: Span,
|
|
646
|
-
className: EditorCompletionItemHighlight,
|
|
647
|
-
childCount: 1
|
|
648
|
-
};
|
|
649
|
-
const getHighlightedLabelDom = (label, highlights) => {
|
|
650
|
-
if (highlights.length === 0) {
|
|
651
|
-
return [label1, text(label)];
|
|
652
|
-
}
|
|
653
|
-
const dom = [];
|
|
654
|
-
const labelDom = {
|
|
655
|
-
type: Div,
|
|
656
|
-
className: Label,
|
|
657
|
-
childCount: 0
|
|
658
|
-
};
|
|
659
|
-
dom.push(labelDom);
|
|
660
|
-
let position = 0;
|
|
661
|
-
for (let i = 0; i < highlights.length; i += 2) {
|
|
662
|
-
const highlightStart = highlights[i];
|
|
663
|
-
const highlightEnd = highlights[i + 1];
|
|
664
|
-
if (position < highlightStart) {
|
|
665
|
-
const beforeText = label.slice(position, highlightStart);
|
|
666
|
-
labelDom.childCount++;
|
|
667
|
-
dom.push(text(beforeText));
|
|
668
|
-
}
|
|
669
|
-
const highlightText = label.slice(highlightStart, highlightEnd);
|
|
670
|
-
labelDom.childCount++;
|
|
671
|
-
dom.push(completionHighlight, text(highlightText));
|
|
672
|
-
position = highlightEnd;
|
|
673
|
-
}
|
|
674
|
-
if (position < label.length) {
|
|
675
|
-
const afterText = label.slice(position);
|
|
676
|
-
labelDom.childCount++;
|
|
677
|
-
dom.push(text(afterText));
|
|
678
|
-
}
|
|
679
|
-
return dom;
|
|
680
|
-
};
|
|
681
|
-
|
|
682
|
-
const getCompletionItemVirtualDom = visibleItem => {
|
|
683
|
-
const {
|
|
684
|
-
top,
|
|
685
|
-
label,
|
|
686
|
-
symbolName,
|
|
687
|
-
highlights,
|
|
688
|
-
focused,
|
|
689
|
-
deprecated,
|
|
690
|
-
fileIcon
|
|
691
|
-
} = visibleItem;
|
|
692
|
-
let className = EditorCompletionItem;
|
|
693
|
-
if (focused) {
|
|
694
|
-
className += ' ' + EditorCompletionItemFocused;
|
|
695
|
-
}
|
|
696
|
-
if (deprecated) {
|
|
697
|
-
className += ' ' + EditorCompletionItemDeprecated;
|
|
698
|
-
}
|
|
699
|
-
return [{
|
|
700
|
-
type: Div,
|
|
701
|
-
role: Option,
|
|
702
|
-
className,
|
|
703
|
-
top,
|
|
704
|
-
childCount: 2
|
|
705
|
-
}, getIconDom(fileIcon, symbolName), ...getHighlightedLabelDom(label, highlights)];
|
|
706
|
-
};
|
|
707
|
-
|
|
708
|
-
const getCompletionItemsVirtualDom = visibleItems => {
|
|
709
|
-
if (visibleItems.length === 0) {
|
|
710
|
-
return [{
|
|
711
|
-
type: Div,
|
|
712
|
-
childCount: 1
|
|
713
|
-
}, text(noResults())];
|
|
714
|
-
}
|
|
715
|
-
const root = {
|
|
716
|
-
type: Div,
|
|
717
|
-
childCount: visibleItems.length
|
|
718
|
-
};
|
|
719
|
-
const dom = [root, ...visibleItems.flatMap(getCompletionItemVirtualDom)];
|
|
720
|
-
return dom;
|
|
721
|
-
};
|
|
722
|
-
|
|
723
|
-
const Deprecated = 1 << 0;
|
|
724
|
-
|
|
725
|
-
const Property = 1;
|
|
726
|
-
const Value = 2;
|
|
727
|
-
const Function$1 = 3;
|
|
728
|
-
const Variable = 4;
|
|
729
|
-
const Keyword = 5;
|
|
730
|
-
const Folder = 6;
|
|
731
|
-
const File = 7;
|
|
732
|
-
const Field = 8;
|
|
733
|
-
|
|
734
|
-
const SymbolProperty = 'SymbolProperty';
|
|
735
|
-
const SymbolValue = 'SymbolValue';
|
|
736
|
-
const SymbolFunction = 'SymbolFunction';
|
|
737
|
-
const SymbolVariable = 'SymbolVariable';
|
|
738
|
-
const SymbolKeyword = 'SymbolKeyword';
|
|
739
|
-
const SymbolDefault = 'SymbolDefault';
|
|
740
|
-
const SymbolField = 'SymbolField';
|
|
741
|
-
const SymbolNone = '';
|
|
742
|
-
|
|
743
|
-
const getSymbolName = item => {
|
|
744
|
-
switch (item.kind) {
|
|
745
|
-
case Property:
|
|
746
|
-
return SymbolProperty;
|
|
747
|
-
case Value:
|
|
748
|
-
return SymbolValue;
|
|
749
|
-
case Function$1:
|
|
750
|
-
return SymbolFunction;
|
|
751
|
-
case Variable:
|
|
752
|
-
return SymbolVariable;
|
|
753
|
-
case Keyword:
|
|
754
|
-
return SymbolKeyword;
|
|
755
|
-
case Field:
|
|
756
|
-
return SymbolField;
|
|
757
|
-
case File:
|
|
758
|
-
return SymbolNone;
|
|
759
|
-
default:
|
|
760
|
-
return SymbolDefault;
|
|
761
|
-
}
|
|
762
|
-
};
|
|
763
|
-
|
|
764
|
-
const getHighlights = item => {
|
|
765
|
-
const {
|
|
766
|
-
matches
|
|
767
|
-
} = item;
|
|
768
|
-
return matches.slice(1);
|
|
769
|
-
};
|
|
770
|
-
|
|
771
|
-
// import * as IconTheme from '../IconTheme/IconTheme.ts'
|
|
772
|
-
|
|
773
|
-
const getLabel = item => {
|
|
774
|
-
return item.label;
|
|
775
|
-
};
|
|
776
|
-
const getFileIcon = item => {
|
|
777
|
-
switch (item.kind) {
|
|
778
|
-
case File:
|
|
779
|
-
// TODO IconTheme.getFileNameIcon(item.label)
|
|
780
|
-
return '';
|
|
781
|
-
case Folder:
|
|
782
|
-
// TODO IconTheme.getFolderNameIcon(item.label)
|
|
783
|
-
return '';
|
|
784
|
-
default:
|
|
785
|
-
return '';
|
|
786
|
-
}
|
|
787
|
-
};
|
|
788
|
-
const getVisibleIem = (item, itemHeight, leadingWord, i, focusedIndex) => {
|
|
789
|
-
return {
|
|
790
|
-
label: getLabel(item),
|
|
791
|
-
symbolName: getSymbolName(item),
|
|
792
|
-
top: i * itemHeight,
|
|
793
|
-
highlights: getHighlights(item),
|
|
794
|
-
focused: i === focusedIndex,
|
|
795
|
-
deprecated: item.flags & Deprecated,
|
|
796
|
-
fileIcon: getFileIcon(item)
|
|
797
|
-
};
|
|
798
|
-
};
|
|
799
|
-
|
|
800
|
-
const getVisibleItems = (filteredItems, itemHeight, leadingWord, minLineY, maxLineY, focusedIndex) => {
|
|
801
|
-
const visibleItems = [];
|
|
802
|
-
for (let i = minLineY; i < maxLineY; i++) {
|
|
803
|
-
const filteredItem = filteredItems[i];
|
|
804
|
-
visibleItems.push(getVisibleIem(filteredItem, itemHeight, leadingWord, i, focusedIndex));
|
|
805
|
-
}
|
|
806
|
-
return visibleItems;
|
|
807
|
-
};
|
|
808
|
-
|
|
809
|
-
/**
|
|
810
|
-
*
|
|
811
|
-
* @param {number} size
|
|
812
|
-
* @param {number} contentSize
|
|
813
|
-
* @param {number} minimumSliderSize
|
|
814
|
-
* @returns
|
|
815
|
-
*/
|
|
816
|
-
const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
|
|
817
|
-
if (size >= contentSize) {
|
|
818
|
-
return 0;
|
|
819
|
-
}
|
|
820
|
-
return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
|
|
821
|
-
};
|
|
822
|
-
const getScrollBarOffset = (delta, finalDelta, size, scrollBarSize) => {
|
|
823
|
-
const scrollBarOffset = delta / finalDelta * (size - scrollBarSize);
|
|
824
|
-
return scrollBarOffset;
|
|
825
|
-
};
|
|
826
|
-
const getScrollBarY = getScrollBarOffset;
|
|
827
|
-
const getScrollBarWidth = (width, longestLineWidth) => {
|
|
828
|
-
if (width > longestLineWidth) {
|
|
829
|
-
return 0;
|
|
830
|
-
}
|
|
831
|
-
return width ** 2 / longestLineWidth;
|
|
832
|
-
};
|
|
833
|
-
const getNewDeltaPercent = (height, scrollBarHeight, relativeY) => {
|
|
834
|
-
const halfScrollBarHeight = scrollBarHeight / 2;
|
|
835
|
-
if (relativeY <= halfScrollBarHeight) {
|
|
836
|
-
// clicked at top
|
|
837
|
-
return {
|
|
838
|
-
percent: 0,
|
|
839
|
-
handleOffset: relativeY
|
|
840
|
-
};
|
|
841
|
-
}
|
|
842
|
-
if (relativeY <= height - halfScrollBarHeight) {
|
|
843
|
-
// clicked in middle
|
|
844
|
-
return {
|
|
845
|
-
percent: (relativeY - halfScrollBarHeight) / (height - scrollBarHeight),
|
|
846
|
-
handleOffset: halfScrollBarHeight
|
|
847
|
-
};
|
|
848
|
-
}
|
|
849
|
-
// clicked at bottom
|
|
850
|
-
return {
|
|
851
|
-
percent: 1,
|
|
852
|
-
handleOffset: scrollBarHeight - height + relativeY
|
|
853
|
-
};
|
|
854
|
-
};
|
|
855
|
-
|
|
856
|
-
const renderItems = {
|
|
857
|
-
isEqual(oldState, newState) {
|
|
858
|
-
return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.focusedIndex === newState.focusedIndex;
|
|
859
|
-
},
|
|
860
|
-
apply(oldState, newState) {
|
|
861
|
-
const visibleItems = getVisibleItems(newState.items, newState.itemHeight, newState.leadingWord, newState.minLineY, newState.maxLineY, newState.focusedIndex);
|
|
862
|
-
const dom = getCompletionItemsVirtualDom(visibleItems);
|
|
863
|
-
return ['setDom', dom];
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
const renderBounds$1 = {
|
|
867
|
-
isEqual(oldState, newState) {
|
|
868
|
-
return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.x === newState.x && oldState.y === newState.y;
|
|
869
|
-
},
|
|
870
|
-
apply(oldState, newState) {
|
|
871
|
-
const {
|
|
872
|
-
x,
|
|
873
|
-
y,
|
|
874
|
-
width,
|
|
875
|
-
height
|
|
876
|
-
} = newState;
|
|
877
|
-
return [/* method */SetBounds, /* x */x, /* y */y, /* width */width, /* height */height];
|
|
878
|
-
}
|
|
879
|
-
};
|
|
880
|
-
const renderHeight = {
|
|
881
|
-
isEqual(oldState, newState) {
|
|
882
|
-
return oldState.items.length === newState.items.length;
|
|
883
|
-
},
|
|
884
|
-
apply(oldState, newState) {
|
|
885
|
-
const {
|
|
886
|
-
itemHeight
|
|
887
|
-
} = newState;
|
|
888
|
-
const contentHeight = newState.items.length * itemHeight;
|
|
889
|
-
return [/* method */SetContentHeight, /* contentHeight */contentHeight];
|
|
890
|
-
}
|
|
891
|
-
};
|
|
892
|
-
const renderNegativeMargin = {
|
|
893
|
-
isEqual(oldState, newState) {
|
|
894
|
-
return oldState.deltaY === newState.deltaY;
|
|
895
|
-
},
|
|
896
|
-
apply(oldState, newState) {
|
|
897
|
-
return [/* method */SetNegativeMargin, /* negativeMargin */-newState.deltaY];
|
|
898
|
-
}
|
|
899
|
-
};
|
|
900
|
-
const renderScrollBar = {
|
|
901
|
-
isEqual(oldState, newState) {
|
|
902
|
-
return oldState.negativeMargin === newState.negativeMargin && oldState.deltaY === newState.deltaY && oldState.height === newState.height && oldState.finalDeltaY === newState.finalDeltaY && oldState.items.length === newState.items.length;
|
|
903
|
-
},
|
|
904
|
-
apply(oldState, newState) {
|
|
905
|
-
const total = newState.items.length;
|
|
906
|
-
const contentHeight = total * newState.itemHeight;
|
|
907
|
-
const scrollBarHeight = getScrollBarSize(newState.height, contentHeight, newState.minimumSliderSize);
|
|
908
|
-
const scrollBarY = getScrollBarY(newState.deltaY, newState.finalDeltaY, newState.height - newState.headerHeight, scrollBarHeight);
|
|
909
|
-
return [/* method */SetScrollBar, /* scrollBarY */scrollBarY, /* scrollBarHeight */scrollBarHeight];
|
|
910
|
-
}
|
|
911
|
-
};
|
|
912
|
-
const render$3 = [renderItems, renderBounds$1, renderHeight, renderNegativeMargin, renderScrollBar];
|
|
913
|
-
const renderCompletion = (oldState, newState) => {
|
|
914
|
-
const commands = [];
|
|
915
|
-
for (const item of render$3) {
|
|
916
|
-
if (!item.isEqual(oldState, newState)) {
|
|
917
|
-
commands.push(item.apply(oldState, newState));
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
return commands;
|
|
921
|
-
};
|
|
922
|
-
|
|
923
|
-
const EmptyMatches = [];
|
|
924
|
-
|
|
925
|
-
const Diagonal = 1;
|
|
926
|
-
const Left = 2;
|
|
927
|
-
|
|
928
|
-
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
929
|
-
|
|
930
|
-
const createTable = size => {
|
|
931
|
-
const table = [];
|
|
932
|
-
for (let i = 0; i < size; i++) {
|
|
933
|
-
const row = new Uint8Array(size);
|
|
934
|
-
table.push(row);
|
|
935
|
-
}
|
|
936
|
-
return table;
|
|
937
|
-
};
|
|
938
|
-
|
|
939
|
-
const isLowerCase = char => {
|
|
940
|
-
return char === char.toLowerCase();
|
|
941
|
-
};
|
|
942
|
-
|
|
943
|
-
const isUpperCase = char => {
|
|
944
|
-
return char === char.toUpperCase();
|
|
945
|
-
};
|
|
946
|
-
|
|
947
|
-
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
948
|
-
const isGap = (columnCharBefore, columnChar) => {
|
|
949
|
-
switch (columnCharBefore) {
|
|
950
|
-
case Dash:
|
|
951
|
-
case Underline:
|
|
952
|
-
case EmptyString:
|
|
953
|
-
case T:
|
|
954
|
-
case Space:
|
|
955
|
-
case Dot:
|
|
956
|
-
return true;
|
|
957
|
-
}
|
|
958
|
-
if (isLowerCase(columnCharBefore) && isUpperCase(columnChar)) {
|
|
959
|
-
return true;
|
|
960
|
-
}
|
|
961
|
-
return false;
|
|
962
|
-
};
|
|
963
|
-
|
|
964
|
-
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
965
|
-
const getScore = (rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, column, wordLength, isDiagonalMatch) => {
|
|
966
|
-
if (rowCharLow !== columnCharLow) {
|
|
967
|
-
return -1;
|
|
968
|
-
}
|
|
969
|
-
const isMatch = rowChar === columnChar;
|
|
970
|
-
if (isMatch) {
|
|
971
|
-
if (isDiagonalMatch) {
|
|
972
|
-
return 8;
|
|
973
|
-
}
|
|
974
|
-
if (isGap(columnCharBefore, columnChar)) {
|
|
975
|
-
return 8;
|
|
976
|
-
}
|
|
977
|
-
return 5;
|
|
978
|
-
}
|
|
979
|
-
if (isGap(columnCharBefore, columnChar)) {
|
|
980
|
-
return 8;
|
|
981
|
-
}
|
|
982
|
-
return 5;
|
|
983
|
-
};
|
|
984
|
-
|
|
985
|
-
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
986
|
-
|
|
987
|
-
const isPatternInWord = (patternLow, patternPos, patternLen, wordLow, wordPos, wordLen) => {
|
|
988
|
-
while (patternPos < patternLen && wordPos < wordLen) {
|
|
989
|
-
if (patternLow[patternPos] === wordLow[wordPos]) {
|
|
990
|
-
patternPos += 1;
|
|
991
|
-
}
|
|
992
|
-
wordPos += 1;
|
|
993
|
-
}
|
|
994
|
-
return patternPos === patternLen; // pattern must be exhausted
|
|
995
|
-
};
|
|
996
|
-
|
|
997
|
-
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
998
|
-
const traceHighlights = (table, arrows, patternLength, wordLength) => {
|
|
999
|
-
let row = patternLength;
|
|
1000
|
-
let column = wordLength;
|
|
1001
|
-
const matches = [];
|
|
1002
|
-
while (row >= 1 && column >= 1) {
|
|
1003
|
-
const arrow = arrows[row][column];
|
|
1004
|
-
if (arrow === Left) {
|
|
1005
|
-
column--;
|
|
1006
|
-
} else if (arrow === Diagonal) {
|
|
1007
|
-
row--;
|
|
1008
|
-
column--;
|
|
1009
|
-
const start = column + 1;
|
|
1010
|
-
while (row >= 1 && column >= 1) {
|
|
1011
|
-
const arrow = arrows[row][column];
|
|
1012
|
-
if (arrow === Left) {
|
|
1013
|
-
break;
|
|
1014
|
-
}
|
|
1015
|
-
if (arrow === Diagonal) {
|
|
1016
|
-
row--;
|
|
1017
|
-
column--;
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
const end = column;
|
|
1021
|
-
matches.unshift(end, start);
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
matches.unshift(table[patternLength][wordLength - 1]);
|
|
1025
|
-
return matches;
|
|
1026
|
-
};
|
|
1027
|
-
|
|
1028
|
-
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
1029
|
-
const gridSize = 128;
|
|
1030
|
-
const table = createTable(gridSize);
|
|
1031
|
-
const arrows = createTable(gridSize);
|
|
1032
|
-
// @ts-ignore
|
|
1033
|
-
createTable(gridSize);
|
|
1034
|
-
const filterCompletionItem = (pattern, word) => {
|
|
1035
|
-
const patternLength = Math.min(pattern.length, gridSize - 1);
|
|
1036
|
-
const wordLength = Math.min(word.length, gridSize - 1);
|
|
1037
|
-
const patternLower = pattern.toLowerCase();
|
|
1038
|
-
const wordLower = word.toLowerCase();
|
|
1039
|
-
if (!isPatternInWord(patternLower, 0, patternLength, wordLower, 0, wordLength)) {
|
|
1040
|
-
return EmptyMatches;
|
|
1041
|
-
}
|
|
1042
|
-
let strongMatch = false;
|
|
1043
|
-
for (let row = 1; row < patternLength + 1; row++) {
|
|
1044
|
-
const rowChar = pattern[row - 1];
|
|
1045
|
-
const rowCharLow = patternLower[row - 1];
|
|
1046
|
-
for (let column = 1; column < wordLength + 1; column++) {
|
|
1047
|
-
const columnChar = word[column - 1];
|
|
1048
|
-
const columnCharLow = wordLower[column - 1];
|
|
1049
|
-
const columnCharBefore = word[column - 2] || '';
|
|
1050
|
-
const isDiagonalMatch = arrows[row - 1][column - 1] === Diagonal;
|
|
1051
|
-
const score = getScore(rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, column, wordLength, isDiagonalMatch);
|
|
1052
|
-
if (row === 1 && score > 5) {
|
|
1053
|
-
strongMatch = true;
|
|
1054
|
-
}
|
|
1055
|
-
let diagonalScore = score + table[row - 1][column - 1];
|
|
1056
|
-
if (isDiagonalMatch && score !== -1) {
|
|
1057
|
-
diagonalScore += 2;
|
|
1058
|
-
}
|
|
1059
|
-
const leftScore = table[row][column - 1];
|
|
1060
|
-
if (leftScore > diagonalScore) {
|
|
1061
|
-
table[row][column] = leftScore;
|
|
1062
|
-
arrows[row][column] = Left;
|
|
1063
|
-
} else {
|
|
1064
|
-
table[row][column] = diagonalScore;
|
|
1065
|
-
arrows[row][column] = Diagonal;
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
if (!strongMatch) {
|
|
1070
|
-
return EmptyMatches;
|
|
1071
|
-
}
|
|
1072
|
-
// printTables(pattern, 0, word, 0)
|
|
1073
|
-
const highlights = traceHighlights(table, arrows, patternLength, wordLength);
|
|
1074
|
-
return highlights;
|
|
1075
|
-
};
|
|
1076
|
-
|
|
1077
|
-
const addEmptyMatch = item => {
|
|
1078
|
-
return {
|
|
1079
|
-
...item,
|
|
1080
|
-
matches: EmptyMatches
|
|
1081
|
-
};
|
|
1082
|
-
};
|
|
1083
|
-
const filterCompletionItems = (completionItems, word) => {
|
|
1084
|
-
if (word === EmptyString) {
|
|
1085
|
-
return completionItems.map(addEmptyMatch);
|
|
1086
|
-
}
|
|
1087
|
-
const filteredCompletions = [];
|
|
1088
|
-
const deprecated = [];
|
|
1089
|
-
for (const completionItem of completionItems) {
|
|
1090
|
-
const {
|
|
1091
|
-
label,
|
|
1092
|
-
flags
|
|
1093
|
-
} = completionItem;
|
|
1094
|
-
const result = filterCompletionItem(word, label);
|
|
1095
|
-
if (result !== EmptyMatches) {
|
|
1096
|
-
if (flags & Deprecated) {
|
|
1097
|
-
// TODO avoid mutation
|
|
1098
|
-
completionItem.matches = EmptyMatches;
|
|
1099
|
-
deprecated.push(completionItem);
|
|
1100
|
-
} else {
|
|
1101
|
-
// TODO avoid mutation
|
|
1102
|
-
completionItem.matches = result;
|
|
1103
|
-
filteredCompletions.push(completionItem);
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
if (deprecated.length > 0) {
|
|
1108
|
-
filteredCompletions.push(...deprecated);
|
|
1109
|
-
}
|
|
1110
|
-
return filteredCompletions;
|
|
1111
|
-
};
|
|
1112
|
-
|
|
1113
|
-
const getListHeight = (itemsLength, itemHeight, maxHeight) => {
|
|
1114
|
-
number$1(itemsLength);
|
|
1115
|
-
number$1(itemHeight);
|
|
1116
|
-
number$1(maxHeight);
|
|
1117
|
-
if (itemsLength === 0) {
|
|
1118
|
-
return itemHeight;
|
|
1119
|
-
}
|
|
1120
|
-
const totalHeight = itemsLength * itemHeight;
|
|
1121
|
-
return Math.min(totalHeight, maxHeight);
|
|
1122
|
-
};
|
|
1123
|
-
|
|
1124
|
-
const RE_WORD_START$1 = /^\w+/;
|
|
1125
|
-
const RE_WORD_END$1 = /\w+$/;
|
|
1126
|
-
const getWordAt = (editor, rowIndex, columnIndex) => {
|
|
1127
|
-
const {
|
|
1128
|
-
lines
|
|
1129
|
-
} = editor;
|
|
1130
|
-
const line = lines[rowIndex];
|
|
1131
|
-
const before = line.slice(0, columnIndex);
|
|
1132
|
-
const matchBefore = before.match(RE_WORD_END$1);
|
|
1133
|
-
const after = line.slice(columnIndex);
|
|
1134
|
-
const matchAfter = after.match(RE_WORD_START$1);
|
|
1135
|
-
let word = EmptyString;
|
|
1136
|
-
if (matchBefore) {
|
|
1137
|
-
word += matchBefore[0];
|
|
1138
|
-
}
|
|
1139
|
-
if (matchAfter) {
|
|
1140
|
-
word += matchAfter[0];
|
|
1141
|
-
}
|
|
1142
|
-
return {
|
|
1143
|
-
word
|
|
1144
|
-
};
|
|
1145
|
-
};
|
|
1146
|
-
const getWordBefore = (editor, rowIndex, columnIndex) => {
|
|
1147
|
-
const {
|
|
1148
|
-
lines
|
|
1149
|
-
} = editor;
|
|
1150
|
-
const line = lines[rowIndex];
|
|
1151
|
-
const before = line.slice(0, columnIndex);
|
|
1152
|
-
const matchBefore = before.match(RE_WORD_END$1);
|
|
1153
|
-
if (matchBefore) {
|
|
1154
|
-
return matchBefore[0];
|
|
1155
|
-
}
|
|
1156
|
-
return EmptyString;
|
|
1157
|
-
};
|
|
1158
|
-
|
|
1159
|
-
const render$2 = (oldState, newState) => {
|
|
1160
|
-
const commands = renderCompletion(oldState, newState);
|
|
1161
|
-
const wrappedCommands = [];
|
|
1162
|
-
const uid = newState.uid;
|
|
1163
|
-
for (const command of commands) {
|
|
1164
|
-
wrappedCommands.push(['Viewlet.send', uid, ...command]);
|
|
1165
|
-
}
|
|
1166
|
-
return wrappedCommands;
|
|
1167
|
-
};
|
|
1168
|
-
const add = widget => {
|
|
1169
|
-
const commands = render$2(widget.oldState, widget.newState);
|
|
1170
|
-
const id = 'EditorCompletion';
|
|
1171
|
-
// TODO how to generate a unique integer id
|
|
1172
|
-
// that doesn't collide with ids created in renderer worker?
|
|
1173
|
-
const uid = widget.newState.uid;
|
|
1174
|
-
const allCommands = [];
|
|
1175
|
-
allCommands.push(['Viewlet.create', id, uid]);
|
|
1176
|
-
allCommands.push(...commands);
|
|
1177
|
-
return allCommands;
|
|
1178
|
-
};
|
|
1179
|
-
const remove$1 = widget => {
|
|
1180
|
-
return [['Viewlet.send', widget.newState.uid, 'dispose']];
|
|
1181
|
-
};
|
|
1182
|
-
const handleEditorType$1 = (editor, state) => {
|
|
1183
|
-
const {
|
|
1184
|
-
unfilteredItems,
|
|
1185
|
-
itemHeight,
|
|
1186
|
-
maxHeight
|
|
1187
|
-
} = state;
|
|
1188
|
-
const {
|
|
1189
|
-
selections
|
|
1190
|
-
} = editor;
|
|
1191
|
-
const rowIndex = selections[0];
|
|
1192
|
-
const columnIndex = selections[1];
|
|
1193
|
-
const x$1 = x(editor, rowIndex, columnIndex);
|
|
1194
|
-
const y$1 = y(editor, rowIndex);
|
|
1195
|
-
const wordAtOffset = getWordBefore(editor, rowIndex, columnIndex);
|
|
1196
|
-
const items = filterCompletionItems(unfilteredItems, wordAtOffset);
|
|
1197
|
-
const newMinLineY = 0;
|
|
1198
|
-
const newMaxLineY = Math.min(items.length, 8);
|
|
1199
|
-
const height = getListHeight(items.length, itemHeight, maxHeight);
|
|
1200
|
-
const finalDeltaY = items.length * itemHeight - height;
|
|
1201
|
-
return {
|
|
1202
|
-
...state,
|
|
1203
|
-
items,
|
|
1204
|
-
x: x$1,
|
|
1205
|
-
y: y$1,
|
|
1206
|
-
minLineY: newMinLineY,
|
|
1207
|
-
maxLineY: newMaxLineY,
|
|
1208
|
-
leadingWord: wordAtOffset,
|
|
1209
|
-
height,
|
|
1210
|
-
finalDeltaY
|
|
1211
|
-
};
|
|
1212
|
-
};
|
|
1213
|
-
const handleEditorDeleteLeft$1 = (editor, state) => {
|
|
1214
|
-
const {
|
|
1215
|
-
unfilteredItems,
|
|
1216
|
-
itemHeight,
|
|
1217
|
-
maxHeight
|
|
1218
|
-
} = state;
|
|
1219
|
-
const {
|
|
1220
|
-
selections
|
|
1221
|
-
} = editor;
|
|
1222
|
-
const rowIndex = selections[0];
|
|
1223
|
-
const columnIndex = selections[1];
|
|
1224
|
-
const x$1 = x(editor, rowIndex, columnIndex);
|
|
1225
|
-
const y$1 = y(editor, rowIndex);
|
|
1226
|
-
const wordAtOffset = getWordBefore(editor, rowIndex, columnIndex);
|
|
1227
|
-
if (!wordAtOffset) {
|
|
1228
|
-
return state;
|
|
1229
|
-
}
|
|
1230
|
-
const items = filterCompletionItems(unfilteredItems, wordAtOffset);
|
|
1231
|
-
const newMaxLineY = Math.min(items.length, 8);
|
|
1232
|
-
const height = getListHeight(items.length, itemHeight, maxHeight);
|
|
1233
|
-
return {
|
|
1234
|
-
...state,
|
|
1235
|
-
items,
|
|
1236
|
-
x: x$1,
|
|
1237
|
-
y: y$1,
|
|
1238
|
-
maxLineY: newMaxLineY,
|
|
1239
|
-
leadingWord: wordAtOffset,
|
|
1240
|
-
height
|
|
1241
|
-
};
|
|
1242
|
-
};
|
|
1243
|
-
|
|
1244
|
-
const EditorCompletionWidget = {
|
|
1245
|
-
__proto__: null,
|
|
1246
|
-
add,
|
|
1247
|
-
handleEditorDeleteLeft: handleEditorDeleteLeft$1,
|
|
1248
|
-
handleEditorType: handleEditorType$1,
|
|
1249
|
-
remove: remove$1,
|
|
1250
|
-
render: render$2
|
|
1251
|
-
};
|
|
1252
|
-
|
|
1253
|
-
const Completion = 'completion';
|
|
1254
|
-
|
|
1255
|
-
const getModule$2 = id => {
|
|
1256
|
-
switch (id) {
|
|
1257
|
-
case Completion:
|
|
1258
|
-
return EditorCompletionWidget;
|
|
1259
|
-
default:
|
|
1260
|
-
throw new Error('unsupported widget');
|
|
1261
|
-
}
|
|
1262
|
-
};
|
|
1263
|
-
|
|
1264
|
-
const applyWidgetChange = (editor, widget, changes) => {
|
|
1265
|
-
const module = getModule$2(widget.id);
|
|
1266
|
-
if (changes.length === 1 && changes[0].origin === EditorType && module.handleEditorType) {
|
|
1267
|
-
const newState = module.handleEditorType(editor, widget.newState);
|
|
1268
|
-
return {
|
|
1269
|
-
...widget,
|
|
1270
|
-
newState
|
|
1271
|
-
};
|
|
1272
|
-
}
|
|
1273
|
-
if (changes.length === 1 && changes[0].origin === DeleteLeft && module.handleEditorDeleteLeft) {
|
|
1274
|
-
const newState = module.handleEditorDeleteLeft(editor, widget.newState);
|
|
1275
|
-
return {
|
|
1276
|
-
...widget,
|
|
1277
|
-
newState
|
|
1278
|
-
};
|
|
1279
|
-
}
|
|
1280
|
-
return widget;
|
|
1281
|
-
};
|
|
1282
|
-
|
|
1283
|
-
const applyWidgetChanges = (editor, changes) => {
|
|
1284
|
-
const widgets = editor.widgets || [];
|
|
1285
|
-
if (widgets.length === 0) {
|
|
1286
|
-
return widgets;
|
|
1287
|
-
}
|
|
1288
|
-
const newWidgets = widgets.map(widget => {
|
|
1289
|
-
const newWidget = applyWidgetChange(editor, widget, changes);
|
|
1290
|
-
return newWidget;
|
|
1291
|
-
});
|
|
1292
|
-
return newWidgets;
|
|
1293
|
-
};
|
|
1294
|
-
|
|
1295
|
-
const splitLines$2 = lines => {
|
|
1296
|
-
if (!lines) {
|
|
1297
|
-
return [];
|
|
1298
|
-
}
|
|
1299
|
-
return lines.split('\n');
|
|
1300
|
-
};
|
|
1301
|
-
|
|
1302
|
-
// based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/common/arrays.ts#L625 (License MIT)
|
|
1303
|
-
|
|
1304
|
-
// @ts-ignore
|
|
1305
|
-
const insertInto = (array, start, newItems) => {
|
|
1306
|
-
const originalLength = array.length;
|
|
1307
|
-
const newItemsLength = newItems.length;
|
|
1308
|
-
array.length = originalLength + newItemsLength;
|
|
1309
|
-
// Move the items after the start index, start from the end so that we don't overwrite any value.
|
|
1310
|
-
for (let i = originalLength - 1; i >= start; i--) {
|
|
1311
|
-
array[i + newItemsLength] = array[i];
|
|
1312
|
-
}
|
|
1313
|
-
for (let i = 0; i < newItemsLength; i++) {
|
|
1314
|
-
array[i + start] = newItems[i];
|
|
1315
|
-
}
|
|
1316
|
-
};
|
|
1317
|
-
|
|
1318
|
-
/**
|
|
1319
|
-
* Alternative to the native Array.splice method, it
|
|
1320
|
-
* can only support limited number of items due to the maximum call stack size limit.
|
|
1321
|
-
*/
|
|
1322
|
-
// @ts-ignore
|
|
1323
|
-
const spliceLargeArray = (array, start, deleteCount, newItems) => {
|
|
1324
|
-
const result = array.splice(start, deleteCount);
|
|
1325
|
-
insertInto(array, start, newItems);
|
|
1326
|
-
return result;
|
|
1327
|
-
};
|
|
1328
|
-
|
|
1329
|
-
const joinLines$2 = lines => {
|
|
1330
|
-
return lines.join('\n');
|
|
364
|
+
const joinLines$2 = lines => {
|
|
365
|
+
return lines.join('\n');
|
|
1331
366
|
};
|
|
1332
367
|
|
|
1333
368
|
// TODO have function for single edit (most common, avoid one array)
|
|
@@ -1471,67 +506,145 @@ const positionAt = (textDocument, offset) => {
|
|
|
1471
506
|
} else {
|
|
1472
507
|
columnIndex = currentOffset - offset;
|
|
1473
508
|
}
|
|
1474
|
-
// for (let i = 0; i < textDocument.lines.length; i++) {
|
|
1475
|
-
// if(currentOffset)
|
|
1476
|
-
// }
|
|
1477
|
-
// TODO
|
|
1478
|
-
return {
|
|
1479
|
-
rowIndex,
|
|
1480
|
-
columnIndex
|
|
1481
|
-
};
|
|
509
|
+
// for (let i = 0; i < textDocument.lines.length; i++) {
|
|
510
|
+
// if(currentOffset)
|
|
511
|
+
// }
|
|
512
|
+
// TODO
|
|
513
|
+
return {
|
|
514
|
+
rowIndex,
|
|
515
|
+
columnIndex
|
|
516
|
+
};
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
// TODO this should be in a separate scrolling module
|
|
520
|
+
const setDeltaY$2 = (state, value) => {
|
|
521
|
+
object(state);
|
|
522
|
+
number$1(value);
|
|
523
|
+
const {
|
|
524
|
+
finalDeltaY,
|
|
525
|
+
deltaY,
|
|
526
|
+
numberOfVisibleLines,
|
|
527
|
+
height,
|
|
528
|
+
scrollBarHeight,
|
|
529
|
+
itemHeight
|
|
530
|
+
} = state;
|
|
531
|
+
const newDeltaY = clamp(value, 0, finalDeltaY);
|
|
532
|
+
if (deltaY === newDeltaY) {
|
|
533
|
+
return state;
|
|
534
|
+
}
|
|
535
|
+
const newMinLineY = Math.floor(newDeltaY / itemHeight);
|
|
536
|
+
const newMaxLineY = newMinLineY + numberOfVisibleLines;
|
|
537
|
+
const scrollBarY = getScrollBarY(newDeltaY, finalDeltaY, height, scrollBarHeight);
|
|
538
|
+
return {
|
|
539
|
+
...state,
|
|
540
|
+
minLineY: newMinLineY,
|
|
541
|
+
maxLineY: newMaxLineY,
|
|
542
|
+
deltaY: newDeltaY,
|
|
543
|
+
scrollBarY
|
|
544
|
+
};
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
const getSelectionPairs = (selections, i) => {
|
|
548
|
+
const first = selections[i];
|
|
549
|
+
const second = selections[i + 1];
|
|
550
|
+
const third = selections[i + 2];
|
|
551
|
+
const fourth = selections[i + 3];
|
|
552
|
+
if (first > third || first === third && second >= fourth) {
|
|
553
|
+
return [third, fourth, first, second, 1];
|
|
554
|
+
}
|
|
555
|
+
return [first, second, third, fourth, 0];
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
const Dash = '-';
|
|
559
|
+
const Dot = '.';
|
|
560
|
+
const EmptyString = '';
|
|
561
|
+
const Space = ' ';
|
|
562
|
+
const Tab = '\t';
|
|
563
|
+
const Underline = '_';
|
|
564
|
+
const T = 't';
|
|
565
|
+
|
|
566
|
+
const getTabCount = string => {
|
|
567
|
+
let count = 0;
|
|
568
|
+
for (const element of string) {
|
|
569
|
+
if (element === Tab) {
|
|
570
|
+
count++;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
return count;
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
const getFontString = (fontWeight, fontSize, fontFamily) => {
|
|
577
|
+
return `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
const getLetterSpacingString = letterSpacing => {
|
|
581
|
+
return `${letterSpacing}px`;
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
const createMeasureContext = () => {
|
|
585
|
+
const canvas = new OffscreenCanvas(0, 0);
|
|
586
|
+
const ctx = /** @type {OffscreenCanvasRenderingContext2D} */canvas.getContext('2d');
|
|
587
|
+
if (!ctx) {
|
|
588
|
+
throw new Error('Failed to get canvas context 2d');
|
|
589
|
+
}
|
|
590
|
+
return ctx;
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
const state$b = {
|
|
594
|
+
ctx: undefined
|
|
595
|
+
};
|
|
596
|
+
const getOrCreate = createCtx => {
|
|
597
|
+
if (state$b.ctx) {
|
|
598
|
+
return state$b.ctx;
|
|
599
|
+
}
|
|
600
|
+
state$b.ctx = createCtx();
|
|
601
|
+
return state$b.ctx;
|
|
602
|
+
};
|
|
603
|
+
|
|
604
|
+
const getContext = () => {
|
|
605
|
+
const ctx = getOrCreate(createMeasureContext);
|
|
606
|
+
return ctx;
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
const measureTextWidth = (text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth) => {
|
|
610
|
+
string(text);
|
|
611
|
+
number$1(fontWeight);
|
|
612
|
+
number$1(fontSize);
|
|
613
|
+
string(fontFamily);
|
|
614
|
+
boolean(isMonoSpaceFont);
|
|
615
|
+
number$1(charWidth);
|
|
616
|
+
if (isMonoSpaceFont) {
|
|
617
|
+
return text.length * charWidth;
|
|
618
|
+
}
|
|
619
|
+
if (typeof letterSpacing !== 'number') {
|
|
620
|
+
throw new TypeError('letterSpacing must be of type number');
|
|
621
|
+
}
|
|
622
|
+
const letterSpacingString = getLetterSpacingString(letterSpacing);
|
|
623
|
+
const fontString = getFontString(fontWeight, fontSize, fontFamily);
|
|
624
|
+
const ctx = getContext();
|
|
625
|
+
// @ts-ignore
|
|
626
|
+
ctx.letterSpacing = letterSpacingString;
|
|
627
|
+
// @ts-ignore
|
|
628
|
+
ctx.font = fontString;
|
|
629
|
+
// @ts-ignore
|
|
630
|
+
const metrics = ctx.measureText(text);
|
|
631
|
+
const width = metrics.width;
|
|
632
|
+
return width;
|
|
1482
633
|
};
|
|
1483
634
|
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
object(state);
|
|
1488
|
-
number$1(value);
|
|
1489
|
-
const {
|
|
1490
|
-
finalDeltaY,
|
|
1491
|
-
deltaY,
|
|
1492
|
-
numberOfVisibleLines,
|
|
1493
|
-
height,
|
|
1494
|
-
scrollBarHeight,
|
|
1495
|
-
itemHeight
|
|
1496
|
-
} = state;
|
|
1497
|
-
const newDeltaY = clamp(value, 0, finalDeltaY);
|
|
1498
|
-
if (deltaY === newDeltaY) {
|
|
1499
|
-
return state;
|
|
635
|
+
const normalizeText = (text, normalize, tabSize) => {
|
|
636
|
+
if (normalize) {
|
|
637
|
+
return text.replaceAll(Tab, Space.repeat(tabSize));
|
|
1500
638
|
}
|
|
1501
|
-
|
|
1502
|
-
const newMaxLineY = newMinLineY + numberOfVisibleLines;
|
|
1503
|
-
const scrollBarY = getScrollBarY(newDeltaY, finalDeltaY, height, scrollBarHeight);
|
|
1504
|
-
return {
|
|
1505
|
-
...state,
|
|
1506
|
-
minLineY: newMinLineY,
|
|
1507
|
-
maxLineY: newMaxLineY,
|
|
1508
|
-
deltaY: newDeltaY,
|
|
1509
|
-
scrollBarY
|
|
1510
|
-
};
|
|
639
|
+
return text;
|
|
1511
640
|
};
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
const first = selections[i];
|
|
1515
|
-
const second = selections[i + 1];
|
|
1516
|
-
const third = selections[i + 2];
|
|
1517
|
-
const fourth = selections[i + 3];
|
|
1518
|
-
if (first > third || first === third && second >= fourth) {
|
|
1519
|
-
return [third, fourth, first, second, 1];
|
|
1520
|
-
}
|
|
1521
|
-
return [first, second, third, fourth, 0];
|
|
641
|
+
const shouldNormalizeText = text => {
|
|
642
|
+
return text.includes(Tab);
|
|
1522
643
|
};
|
|
1523
644
|
|
|
1524
645
|
// TODO visible selections could also be uint16array
|
|
1525
646
|
// [top1, left1, width1, height1, top2, left2, width2, height2...]
|
|
1526
|
-
|
|
1527
|
-
let count = 0;
|
|
1528
|
-
for (const element of string) {
|
|
1529
|
-
if (element === '\t') {
|
|
1530
|
-
count++;
|
|
1531
|
-
}
|
|
1532
|
-
}
|
|
1533
|
-
return count;
|
|
1534
|
-
};
|
|
647
|
+
|
|
1535
648
|
const getX = (line, column, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, difference = 0) => {
|
|
1536
649
|
if (!line) {
|
|
1537
650
|
return 0;
|
|
@@ -1556,6 +669,7 @@ const getX = (line, column, fontWeight, fontSize, fontFamily, isMonospaceFont, l
|
|
|
1556
669
|
const partialText = normalizedLine.slice(0, column + tabCount);
|
|
1557
670
|
return measureTextWidth(partialText, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, averageCharWidth) - halfCursorWidth + difference;
|
|
1558
671
|
};
|
|
672
|
+
|
|
1559
673
|
const getY = (row, minLineY, rowHeight) => {
|
|
1560
674
|
return (row - minLineY) * rowHeight;
|
|
1561
675
|
};
|
|
@@ -1643,6 +757,9 @@ const push = (selections, startRowIndex, startColumnIndex, endRowIndex, endColum
|
|
|
1643
757
|
newSelections[oldLength + 4] = endColumnIndex;
|
|
1644
758
|
return newSelections;
|
|
1645
759
|
};
|
|
760
|
+
|
|
761
|
+
// TODO maybe only accept sorted selection edits in the first place
|
|
762
|
+
|
|
1646
763
|
const emptyCursors = [];
|
|
1647
764
|
const getCursorArray = (visibleCursors, isFocused) => {
|
|
1648
765
|
if (!isFocused) {
|
|
@@ -1808,9 +925,9 @@ const applyEdit$1 = (editor, changes) => {
|
|
|
1808
925
|
|
|
1809
926
|
// TODO
|
|
1810
927
|
const setDeltaYFixedValue$1 = (editor, value) => {
|
|
1811
|
-
return setDeltaY$
|
|
928
|
+
return setDeltaY$2(editor, value);
|
|
1812
929
|
};
|
|
1813
|
-
const setDeltaY$
|
|
930
|
+
const setDeltaY$1 = (editor, value) => {
|
|
1814
931
|
return setDeltaYFixedValue$1(editor, editor.deltaY + value);
|
|
1815
932
|
};
|
|
1816
933
|
const isAutoClosingChange = change => {
|
|
@@ -2018,34 +1135,6 @@ const set$6 = (id, oldEditor, newEditor) => {
|
|
|
2018
1135
|
};
|
|
2019
1136
|
};
|
|
2020
1137
|
|
|
2021
|
-
// TODO this should be in a separate scrolling module
|
|
2022
|
-
const setDeltaY$1 = (state, value) => {
|
|
2023
|
-
object(state);
|
|
2024
|
-
number$1(value);
|
|
2025
|
-
const {
|
|
2026
|
-
finalDeltaY,
|
|
2027
|
-
deltaY,
|
|
2028
|
-
numberOfVisibleLines,
|
|
2029
|
-
height,
|
|
2030
|
-
scrollBarHeight,
|
|
2031
|
-
itemHeight
|
|
2032
|
-
} = state;
|
|
2033
|
-
const newDeltaY = clamp(value, 0, finalDeltaY);
|
|
2034
|
-
if (deltaY === newDeltaY) {
|
|
2035
|
-
return state;
|
|
2036
|
-
}
|
|
2037
|
-
const newMinLineY = Math.floor(newDeltaY / itemHeight);
|
|
2038
|
-
const newMaxLineY = newMinLineY + numberOfVisibleLines;
|
|
2039
|
-
const scrollBarY = getScrollBarY(newDeltaY, finalDeltaY, height, scrollBarHeight);
|
|
2040
|
-
return {
|
|
2041
|
-
...state,
|
|
2042
|
-
minLineY: newMinLineY,
|
|
2043
|
-
maxLineY: newMaxLineY,
|
|
2044
|
-
deltaY: newDeltaY,
|
|
2045
|
-
scrollBarY
|
|
2046
|
-
};
|
|
2047
|
-
};
|
|
2048
|
-
|
|
2049
1138
|
const Two = '2.0';
|
|
2050
1139
|
class AssertionError extends Error {
|
|
2051
1140
|
constructor(message) {
|
|
@@ -2090,7 +1179,7 @@ const set$5 = (id, fn) => {
|
|
|
2090
1179
|
const get$5 = id => {
|
|
2091
1180
|
return state$1$1.callbacks[id];
|
|
2092
1181
|
};
|
|
2093
|
-
const remove = id => {
|
|
1182
|
+
const remove$1 = id => {
|
|
2094
1183
|
delete state$1$1.callbacks[id];
|
|
2095
1184
|
};
|
|
2096
1185
|
const state$a = {
|
|
@@ -2136,7 +1225,7 @@ const resolve = (id, args) => {
|
|
|
2136
1225
|
return;
|
|
2137
1226
|
}
|
|
2138
1227
|
fn(args);
|
|
2139
|
-
remove(id);
|
|
1228
|
+
remove$1(id);
|
|
2140
1229
|
};
|
|
2141
1230
|
const create$2$1 = (method, params) => {
|
|
2142
1231
|
const {
|
|
@@ -2160,7 +1249,7 @@ class JsonRpcError extends Error {
|
|
|
2160
1249
|
this.name = 'JsonRpcError';
|
|
2161
1250
|
}
|
|
2162
1251
|
}
|
|
2163
|
-
const NewLine$
|
|
1252
|
+
const NewLine$3 = '\n';
|
|
2164
1253
|
const DomException = 'DOMException';
|
|
2165
1254
|
const ReferenceError$1 = 'ReferenceError';
|
|
2166
1255
|
const SyntaxError$1 = 'SyntaxError';
|
|
@@ -2208,20 +1297,20 @@ const constructError = (message, type, name) => {
|
|
|
2208
1297
|
return new ErrorConstructor(message);
|
|
2209
1298
|
};
|
|
2210
1299
|
const getNewLineIndex$2 = (string, startIndex = undefined) => {
|
|
2211
|
-
return string.indexOf(NewLine$
|
|
1300
|
+
return string.indexOf(NewLine$3, startIndex);
|
|
2212
1301
|
};
|
|
2213
1302
|
const joinLines$1 = lines => {
|
|
2214
|
-
return lines.join(NewLine$
|
|
1303
|
+
return lines.join(NewLine$3);
|
|
2215
1304
|
};
|
|
2216
1305
|
const MethodNotFound = -32601;
|
|
2217
1306
|
const Custom = -32001;
|
|
2218
1307
|
const splitLines$1 = lines => {
|
|
2219
|
-
return lines.split(NewLine$
|
|
1308
|
+
return lines.split(NewLine$3);
|
|
2220
1309
|
};
|
|
2221
1310
|
const getParentStack = error => {
|
|
2222
1311
|
let parentStack = error.stack || error.data || error.message || '';
|
|
2223
1312
|
if (parentStack.startsWith(' at')) {
|
|
2224
|
-
parentStack = error.message + NewLine$
|
|
1313
|
+
parentStack = error.message + NewLine$3 + parentStack;
|
|
2225
1314
|
}
|
|
2226
1315
|
return parentStack;
|
|
2227
1316
|
};
|
|
@@ -2233,14 +1322,14 @@ const restoreJsonRpcError = error => {
|
|
|
2233
1322
|
if (error && error.code && error.code === MethodNotFound) {
|
|
2234
1323
|
const restoredError = new JsonRpcError(error.message);
|
|
2235
1324
|
const parentStack = getParentStack(error);
|
|
2236
|
-
restoredError.stack = parentStack + NewLine$
|
|
1325
|
+
restoredError.stack = parentStack + NewLine$3 + currentStack;
|
|
2237
1326
|
return restoredError;
|
|
2238
1327
|
}
|
|
2239
1328
|
if (error && error.message) {
|
|
2240
1329
|
const restoredError = constructError(error.message, error.type, error.name);
|
|
2241
1330
|
if (error.data) {
|
|
2242
1331
|
if (error.data.stack && error.data.type && error.message) {
|
|
2243
|
-
restoredError.stack = error.data.type + ': ' + error.message + NewLine$
|
|
1332
|
+
restoredError.stack = error.data.type + ': ' + error.message + NewLine$3 + error.data.stack + NewLine$3 + currentStack;
|
|
2244
1333
|
} else if (error.data.stack) {
|
|
2245
1334
|
restoredError.stack = error.data.stack;
|
|
2246
1335
|
}
|
|
@@ -2321,7 +1410,7 @@ const getErrorResponse = (message, error, preparePrettyError, logError) => {
|
|
|
2321
1410
|
const errorProperty = getErrorProperty(error, prettyError);
|
|
2322
1411
|
return create$1$1(message, errorProperty);
|
|
2323
1412
|
};
|
|
2324
|
-
const create$
|
|
1413
|
+
const create$5 = (message, result) => {
|
|
2325
1414
|
return {
|
|
2326
1415
|
jsonrpc: Two,
|
|
2327
1416
|
id: message.id,
|
|
@@ -2330,7 +1419,7 @@ const create$4 = (message, result) => {
|
|
|
2330
1419
|
};
|
|
2331
1420
|
const getSuccessResponse = (message, result) => {
|
|
2332
1421
|
const resultProperty = result ?? null;
|
|
2333
|
-
return create$
|
|
1422
|
+
return create$5(message, resultProperty);
|
|
2334
1423
|
};
|
|
2335
1424
|
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
|
|
2336
1425
|
try {
|
|
@@ -2527,7 +1616,7 @@ const waitForFirstMessage$1 = async port => {
|
|
|
2527
1616
|
return event;
|
|
2528
1617
|
};
|
|
2529
1618
|
|
|
2530
|
-
const create$
|
|
1619
|
+
const create$4 = async () => {
|
|
2531
1620
|
const {
|
|
2532
1621
|
port1,
|
|
2533
1622
|
port2
|
|
@@ -2572,7 +1661,7 @@ const wrap$3 = port => {
|
|
|
2572
1661
|
|
|
2573
1662
|
const IpcParentWithExtensionHostWorker = {
|
|
2574
1663
|
__proto__: null,
|
|
2575
|
-
create: create$
|
|
1664
|
+
create: create$4,
|
|
2576
1665
|
wrap: wrap$3
|
|
2577
1666
|
};
|
|
2578
1667
|
|
|
@@ -2580,7 +1669,7 @@ const sendMessagePortToSyntaxHighlightingWorker = async port => {
|
|
|
2580
1669
|
await invokeAndTransfer([port], 'SendMessagePortToSyntaxHighlightingWorker.sendMessagePortToSyntaxHighlightingWorker', port, 'HandleMessagePort.handleMessagePort');
|
|
2581
1670
|
};
|
|
2582
1671
|
|
|
2583
|
-
const create$
|
|
1672
|
+
const create$3 = async () => {
|
|
2584
1673
|
const {
|
|
2585
1674
|
port1,
|
|
2586
1675
|
port2
|
|
@@ -2625,7 +1714,7 @@ const wrap$1 = port => {
|
|
|
2625
1714
|
|
|
2626
1715
|
const IpcParentWithSyntaxHighlightingWorker = {
|
|
2627
1716
|
__proto__: null,
|
|
2628
|
-
create: create$
|
|
1717
|
+
create: create$3,
|
|
2629
1718
|
wrap: wrap$1
|
|
2630
1719
|
};
|
|
2631
1720
|
|
|
@@ -2633,7 +1722,7 @@ const sendMessagePortToRendererProcess = async port => {
|
|
|
2633
1722
|
await invokeAndTransfer([port], 'SendMessagePortToRendererProcess.sendMessagePortToRendererProcess', port, 'HandleMessagePort.handleMessagePort');
|
|
2634
1723
|
};
|
|
2635
1724
|
|
|
2636
|
-
const create$
|
|
1725
|
+
const create$2 = async () => {
|
|
2637
1726
|
const {
|
|
2638
1727
|
port1,
|
|
2639
1728
|
port2
|
|
@@ -2678,7 +1767,7 @@ const wrap = port => {
|
|
|
2678
1767
|
|
|
2679
1768
|
const IpcParentWithRendererProcess = {
|
|
2680
1769
|
__proto__: null,
|
|
2681
|
-
create: create$
|
|
1770
|
+
create: create$2,
|
|
2682
1771
|
wrap
|
|
2683
1772
|
};
|
|
2684
1773
|
|
|
@@ -2695,7 +1784,7 @@ const getModule$1 = method => {
|
|
|
2695
1784
|
}
|
|
2696
1785
|
};
|
|
2697
1786
|
|
|
2698
|
-
const create = async ({
|
|
1787
|
+
const create$1 = async ({
|
|
2699
1788
|
method,
|
|
2700
1789
|
...options
|
|
2701
1790
|
}) => {
|
|
@@ -2713,7 +1802,7 @@ const create = async ({
|
|
|
2713
1802
|
const createRpc = method => {
|
|
2714
1803
|
let _ipc;
|
|
2715
1804
|
const listen = async () => {
|
|
2716
|
-
const ipc = await create({
|
|
1805
|
+
const ipc = await create$1({
|
|
2717
1806
|
method
|
|
2718
1807
|
});
|
|
2719
1808
|
handleIpc(ipc);
|
|
@@ -2856,7 +1945,7 @@ const createEditor = async ({
|
|
|
2856
1945
|
// TODO avoid creating intermediate editors here
|
|
2857
1946
|
const newEditor1 = setBounds(editor, x, y, width, height, 9);
|
|
2858
1947
|
const newEditor2 = setText(newEditor1, content);
|
|
2859
|
-
const newEditor3 = setDeltaY$
|
|
1948
|
+
const newEditor3 = setDeltaY$2(newEditor2, 0);
|
|
2860
1949
|
const newEditor4 = {
|
|
2861
1950
|
...newEditor3,
|
|
2862
1951
|
focused: true
|
|
@@ -2967,14 +2056,188 @@ const replaceRange = (editor, ranges, replacement, origin) => {
|
|
|
2967
2056
|
origin
|
|
2968
2057
|
});
|
|
2969
2058
|
}
|
|
2970
|
-
return changes;
|
|
2059
|
+
return changes;
|
|
2060
|
+
};
|
|
2061
|
+
|
|
2062
|
+
const editorReplaceSelections = (editor, replacement, origin) => {
|
|
2063
|
+
const {
|
|
2064
|
+
selections
|
|
2065
|
+
} = editor;
|
|
2066
|
+
return replaceRange(editor, selections, replacement, origin);
|
|
2067
|
+
};
|
|
2068
|
+
|
|
2069
|
+
const getAccurateColumnIndexAscii = (line, guess, averageCharWidth, eventX, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth) => {
|
|
2070
|
+
for (let i = guess; i < line.length; i++) {
|
|
2071
|
+
const width = measureTextWidth(line.slice(0, i), fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
2072
|
+
if (eventX - width < averageCharWidth / 2) {
|
|
2073
|
+
return i;
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
return line.length;
|
|
2077
|
+
};
|
|
2078
|
+
|
|
2079
|
+
const supported = () => {
|
|
2080
|
+
return 'Segmenter' in Intl;
|
|
2081
|
+
};
|
|
2082
|
+
const create = () => {
|
|
2083
|
+
// @ts-ignore
|
|
2084
|
+
const segmenter = new Intl.Segmenter();
|
|
2085
|
+
return {
|
|
2086
|
+
at(line, index) {
|
|
2087
|
+
const segments = segmenter.segment(line);
|
|
2088
|
+
return segments.containing(index);
|
|
2089
|
+
},
|
|
2090
|
+
visualIndex(line, index) {
|
|
2091
|
+
const segments = segmenter.segment(line);
|
|
2092
|
+
let currentVisualIndex = 0;
|
|
2093
|
+
for (const segment of segments) {
|
|
2094
|
+
if (segment.index >= index) {
|
|
2095
|
+
return currentVisualIndex;
|
|
2096
|
+
}
|
|
2097
|
+
currentVisualIndex++;
|
|
2098
|
+
}
|
|
2099
|
+
return currentVisualIndex;
|
|
2100
|
+
},
|
|
2101
|
+
modelIndex(line, visualIndex) {
|
|
2102
|
+
const segments = segmenter.segment(line);
|
|
2103
|
+
let currentVisualIndex = 0;
|
|
2104
|
+
for (const segment of segments) {
|
|
2105
|
+
if (currentVisualIndex >= visualIndex) {
|
|
2106
|
+
return segment.index;
|
|
2107
|
+
}
|
|
2108
|
+
currentVisualIndex++;
|
|
2109
|
+
}
|
|
2110
|
+
return line.length;
|
|
2111
|
+
},
|
|
2112
|
+
getSegments(line) {
|
|
2113
|
+
return segmenter.segment(line);
|
|
2114
|
+
}
|
|
2115
|
+
};
|
|
2116
|
+
};
|
|
2117
|
+
|
|
2118
|
+
// @ts-ignore
|
|
2119
|
+
const getAccurateColumnIndexUnicode = (line, guess, averageCharWidth, eventX, fontWeight, fontSize, fontFamily, letterSpacing) => {
|
|
2120
|
+
const segmenter = create();
|
|
2121
|
+
const segments = segmenter.getSegments(line);
|
|
2122
|
+
const isMonospaceFont = false;
|
|
2123
|
+
const charWidth = 0;
|
|
2124
|
+
for (const segment of segments) {
|
|
2125
|
+
const width = measureTextWidth(line.slice(0, segment.index), fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
2126
|
+
if (eventX - width < averageCharWidth) {
|
|
2127
|
+
return segment.index;
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
return line.length;
|
|
2131
|
+
};
|
|
2132
|
+
|
|
2133
|
+
const RE_ASCII = /^[\p{ASCII}]*$/u;
|
|
2134
|
+
const isAscii = line => {
|
|
2135
|
+
return RE_ASCII.test(line);
|
|
2136
|
+
};
|
|
2137
|
+
|
|
2138
|
+
// @ts-ignore
|
|
2139
|
+
const guessOffset = (eventX, averageCharWidth) => {
|
|
2140
|
+
const guess = Math.round(eventX / averageCharWidth);
|
|
2141
|
+
return guess;
|
|
2142
|
+
};
|
|
2143
|
+
|
|
2144
|
+
// @ts-ignore
|
|
2145
|
+
const normalizeGuess = (line, guess, tabSize) => {
|
|
2146
|
+
let normalizedGuess = guess;
|
|
2147
|
+
for (let i = 0; i < guess; i++) {
|
|
2148
|
+
if (line[i] === Tab) {
|
|
2149
|
+
normalizedGuess -= tabSize - 1;
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
return normalizedGuess;
|
|
2153
|
+
};
|
|
2154
|
+
|
|
2155
|
+
// @ts-ignore
|
|
2156
|
+
const getAccurateColumnIndex = (line, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth, tabSize, eventX) => {
|
|
2157
|
+
string(line);
|
|
2158
|
+
number$1(fontWeight);
|
|
2159
|
+
number$1(fontSize);
|
|
2160
|
+
string(fontFamily);
|
|
2161
|
+
number$1(letterSpacing);
|
|
2162
|
+
boolean(isMonospaceFont);
|
|
2163
|
+
number$1(charWidth);
|
|
2164
|
+
number$1(tabSize);
|
|
2165
|
+
number$1(eventX);
|
|
2166
|
+
// Assert.greaterZero(charWidth)
|
|
2167
|
+
const guess = guessOffset(eventX, charWidth);
|
|
2168
|
+
const normalize = shouldNormalizeText(line);
|
|
2169
|
+
const normalizedGuess = normalizeGuess(line, guess, tabSize);
|
|
2170
|
+
const text = line.slice(0, normalizedGuess);
|
|
2171
|
+
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
2172
|
+
const actual = measureTextWidth(normalizedText, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
2173
|
+
const isAscii$1 = isAscii(line);
|
|
2174
|
+
if (isAscii$1) {
|
|
2175
|
+
if (Math.abs(eventX - actual) < charWidth / 2) {
|
|
2176
|
+
return normalizedGuess;
|
|
2177
|
+
}
|
|
2178
|
+
return getAccurateColumnIndexAscii(line, normalizedGuess, charWidth, eventX, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
2179
|
+
}
|
|
2180
|
+
return getAccurateColumnIndexUnicode(line, normalizedGuess, charWidth, eventX, fontWeight, fontSize, fontFamily, letterSpacing);
|
|
2181
|
+
};
|
|
2182
|
+
|
|
2183
|
+
const at = (editor, eventX, eventY) => {
|
|
2184
|
+
object(editor);
|
|
2185
|
+
number$1(eventX);
|
|
2186
|
+
number$1(eventY);
|
|
2187
|
+
const {
|
|
2188
|
+
y,
|
|
2189
|
+
deltaY,
|
|
2190
|
+
rowHeight,
|
|
2191
|
+
fontSize,
|
|
2192
|
+
fontWeight,
|
|
2193
|
+
fontFamily,
|
|
2194
|
+
letterSpacing,
|
|
2195
|
+
lines,
|
|
2196
|
+
tabSize,
|
|
2197
|
+
differences,
|
|
2198
|
+
isMonospaceFont,
|
|
2199
|
+
charWidth
|
|
2200
|
+
} = editor;
|
|
2201
|
+
const rowIndex = Math.floor((eventY - y + deltaY) / rowHeight);
|
|
2202
|
+
if (rowIndex < 0) {
|
|
2203
|
+
return {
|
|
2204
|
+
rowIndex: 0,
|
|
2205
|
+
columnIndex: 0
|
|
2206
|
+
};
|
|
2207
|
+
}
|
|
2208
|
+
const clampedRowIndex = clamp(rowIndex, 0, lines.length - 1);
|
|
2209
|
+
const line = lines[clampedRowIndex];
|
|
2210
|
+
const columnIndex = getAccurateColumnIndex(line, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth, tabSize, eventX);
|
|
2211
|
+
return {
|
|
2212
|
+
rowIndex: clampedRowIndex,
|
|
2213
|
+
columnIndex
|
|
2214
|
+
};
|
|
2971
2215
|
};
|
|
2972
2216
|
|
|
2973
|
-
|
|
2217
|
+
/**
|
|
2218
|
+
* @deprecated this doesn't work for variable width characters (unicode/emoji).
|
|
2219
|
+
* Use position computation in renderer process instead
|
|
2220
|
+
*
|
|
2221
|
+
* @param {object} editor
|
|
2222
|
+
* @param {number} rowIndex
|
|
2223
|
+
* @param {number} columnIndex
|
|
2224
|
+
* @returns
|
|
2225
|
+
*/
|
|
2226
|
+
const x = (editor, rowIndex, columnIndex) => {
|
|
2974
2227
|
const {
|
|
2975
|
-
|
|
2228
|
+
columnWidth,
|
|
2229
|
+
x
|
|
2976
2230
|
} = editor;
|
|
2977
|
-
|
|
2231
|
+
const offsetX = columnIndex * columnWidth + x;
|
|
2232
|
+
return offsetX;
|
|
2233
|
+
};
|
|
2234
|
+
const y = (editor, rowIndex) => {
|
|
2235
|
+
const {
|
|
2236
|
+
rowHeight,
|
|
2237
|
+
y
|
|
2238
|
+
} = editor;
|
|
2239
|
+
const offsetY = (rowIndex + 1) * rowHeight + y;
|
|
2240
|
+
return offsetY;
|
|
2978
2241
|
};
|
|
2979
2242
|
|
|
2980
2243
|
const state$7 = {
|
|
@@ -3083,8 +2346,10 @@ const cancelSelection = editor => {
|
|
|
3083
2346
|
return scheduleSelections(editor, newSelections);
|
|
3084
2347
|
};
|
|
3085
2348
|
|
|
2349
|
+
const Completion = 'completion';
|
|
2350
|
+
|
|
3086
2351
|
const isCompletionWidget = widget => {
|
|
3087
|
-
return widget.id ===
|
|
2352
|
+
return widget.id === Completion;
|
|
3088
2353
|
};
|
|
3089
2354
|
const closeCompletion = editor => {
|
|
3090
2355
|
const {
|
|
@@ -3156,17 +2421,6 @@ const compositionEnd = (editor, data) => {
|
|
|
3156
2421
|
return scheduleDocumentAndCursorsSelections(editor, changes);
|
|
3157
2422
|
};
|
|
3158
2423
|
|
|
3159
|
-
/**
|
|
3160
|
-
*
|
|
3161
|
-
* @param {string} string
|
|
3162
|
-
* @param {number|undefined} startIndex
|
|
3163
|
-
* @returns
|
|
3164
|
-
*/
|
|
3165
|
-
// @ts-ignore
|
|
3166
|
-
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
3167
|
-
return string.indexOf('\n', startIndex);
|
|
3168
|
-
};
|
|
3169
|
-
|
|
3170
2424
|
const normalizeLine$1 = line => {
|
|
3171
2425
|
if (line.startsWith('Error: ')) {
|
|
3172
2426
|
return line.slice(`Error: `.length);
|
|
@@ -3176,7 +2430,17 @@ const normalizeLine$1 = line => {
|
|
|
3176
2430
|
}
|
|
3177
2431
|
return line;
|
|
3178
2432
|
};
|
|
3179
|
-
|
|
2433
|
+
const getCombinedMessage$1 = (error, message) => {
|
|
2434
|
+
const stringifiedError = normalizeLine$1(`${error}`);
|
|
2435
|
+
if (message) {
|
|
2436
|
+
return `${message}: ${stringifiedError}`;
|
|
2437
|
+
}
|
|
2438
|
+
return stringifiedError;
|
|
2439
|
+
};
|
|
2440
|
+
const NewLine$2 = '\n';
|
|
2441
|
+
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
2442
|
+
return string.indexOf(NewLine$2, startIndex);
|
|
2443
|
+
};
|
|
3180
2444
|
const mergeStacks$1 = (parent, child) => {
|
|
3181
2445
|
if (!child) {
|
|
3182
2446
|
return parent;
|
|
@@ -3194,28 +2458,6 @@ const mergeStacks$1 = (parent, child) => {
|
|
|
3194
2458
|
}
|
|
3195
2459
|
return child;
|
|
3196
2460
|
};
|
|
3197
|
-
|
|
3198
|
-
// @ts-nocheck
|
|
3199
|
-
const stringifyError = error => {
|
|
3200
|
-
if (error instanceof DOMException && error.message) {
|
|
3201
|
-
return `DOMException: ${error.message}`;
|
|
3202
|
-
}
|
|
3203
|
-
const errorPrefixes = ['Error: ', 'VError: '];
|
|
3204
|
-
const stringifiedError = `${error}`;
|
|
3205
|
-
for (const errorPrefix of errorPrefixes) {
|
|
3206
|
-
if (stringifiedError.startsWith(errorPrefix)) {
|
|
3207
|
-
return stringifiedError.slice(errorPrefix.length);
|
|
3208
|
-
}
|
|
3209
|
-
}
|
|
3210
|
-
return stringifiedError;
|
|
3211
|
-
};
|
|
3212
|
-
const getCombinedMessage$1 = (error, message) => {
|
|
3213
|
-
const stringifiedError = stringifyError(error);
|
|
3214
|
-
if (message) {
|
|
3215
|
-
return `${message}: ${stringifiedError}`;
|
|
3216
|
-
}
|
|
3217
|
-
return `${stringifiedError}`;
|
|
3218
|
-
};
|
|
3219
2461
|
let VError$1 = class VError extends Error {
|
|
3220
2462
|
constructor(error, message) {
|
|
3221
2463
|
const combinedMessage = getCombinedMessage$1(error, message);
|
|
@@ -3225,12 +2467,16 @@ let VError$1 = class VError extends Error {
|
|
|
3225
2467
|
this.stack = mergeStacks$1(this.stack, error.stack);
|
|
3226
2468
|
}
|
|
3227
2469
|
if (error.codeFrame) {
|
|
2470
|
+
// @ts-ignore
|
|
3228
2471
|
this.codeFrame = error.codeFrame;
|
|
3229
2472
|
}
|
|
2473
|
+
if (error.code) {
|
|
2474
|
+
// @ts-ignore
|
|
2475
|
+
this.code = error.code;
|
|
2476
|
+
}
|
|
3230
2477
|
}
|
|
3231
2478
|
};
|
|
3232
2479
|
|
|
3233
|
-
// @ts-ignore
|
|
3234
2480
|
const writeText = async text => {
|
|
3235
2481
|
try {
|
|
3236
2482
|
string(text);
|
|
@@ -3430,7 +2676,7 @@ const characterLeft = (line, columnIndex) => {
|
|
|
3430
2676
|
if (!supported()) {
|
|
3431
2677
|
return 1;
|
|
3432
2678
|
}
|
|
3433
|
-
const segmenter = create
|
|
2679
|
+
const segmenter = create();
|
|
3434
2680
|
const last = segmenter.at(line, columnIndex - 1);
|
|
3435
2681
|
return columnIndex - last.index;
|
|
3436
2682
|
};
|
|
@@ -3443,7 +2689,7 @@ const characterRight = (line, columnIndex) => {
|
|
|
3443
2689
|
if (!supported()) {
|
|
3444
2690
|
return 1;
|
|
3445
2691
|
}
|
|
3446
|
-
const segmenter = create
|
|
2692
|
+
const segmenter = create();
|
|
3447
2693
|
const next = segmenter.at(line, columnIndex);
|
|
3448
2694
|
return next.segment.length;
|
|
3449
2695
|
};
|
|
@@ -3647,9 +2893,6 @@ const cursorSet = (editor, rowIndex, columnIndex) => {
|
|
|
3647
2893
|
return scheduleSelections(editor, selectionEdits);
|
|
3648
2894
|
};
|
|
3649
2895
|
|
|
3650
|
-
// @ts-ignore
|
|
3651
|
-
|
|
3652
|
-
// @ts-ignore
|
|
3653
2896
|
const moveSelectionWithoutIntlSegmenter = (selections, i, selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) => {
|
|
3654
2897
|
if (selectionStartRow === 0) {
|
|
3655
2898
|
moveRangeToPosition$1(selections, i, 0, 0);
|
|
@@ -3657,13 +2900,9 @@ const moveSelectionWithoutIntlSegmenter = (selections, i, selectionStartRow, sel
|
|
|
3657
2900
|
moveRangeToPosition$1(selections, i, selectionStartRow - 1, selectionStartColumn);
|
|
3658
2901
|
}
|
|
3659
2902
|
};
|
|
3660
|
-
|
|
3661
|
-
// @ts-ignore
|
|
3662
2903
|
const getNewSelections$8 = selections => {
|
|
3663
2904
|
return map(selections, moveSelectionWithoutIntlSegmenter);
|
|
3664
2905
|
};
|
|
3665
|
-
|
|
3666
|
-
// @ts-ignore
|
|
3667
2906
|
const cursorVertical = (editor, getPosition, getEdgePosition, delta) => {
|
|
3668
2907
|
// if (TextSegmenter.supported()) {
|
|
3669
2908
|
// return editorCursorsVerticalWithIntlSegmenter(
|
|
@@ -3679,7 +2918,6 @@ const cursorVertical = (editor, getPosition, getEdgePosition, delta) => {
|
|
|
3679
2918
|
return scheduleSelections(editor, newSelections);
|
|
3680
2919
|
};
|
|
3681
2920
|
|
|
3682
|
-
// @ts-ignore
|
|
3683
2921
|
const cursorUp = editor => {
|
|
3684
2922
|
return cursorVertical(editor);
|
|
3685
2923
|
};
|
|
@@ -3707,7 +2945,6 @@ const cursorWordRight = editor => {
|
|
|
3707
2945
|
return editorCursorHorizontalRight(editor, wordRight);
|
|
3708
2946
|
};
|
|
3709
2947
|
|
|
3710
|
-
// @ts-ignore
|
|
3711
2948
|
const cutLine = async editor => {
|
|
3712
2949
|
const {
|
|
3713
2950
|
lines,
|
|
@@ -3719,7 +2956,6 @@ const cutLine = async editor => {
|
|
|
3719
2956
|
const changes = replaceRange(editor, replaceRange$1, [''], EditorCut);
|
|
3720
2957
|
const selectionChanges = new Uint32Array([startRowIndex, 0, startRowIndex, 0]);
|
|
3721
2958
|
await writeText(line);
|
|
3722
|
-
// @ts-ignore
|
|
3723
2959
|
return scheduleDocumentAndCursorsSelections(editor, changes, selectionChanges);
|
|
3724
2960
|
};
|
|
3725
2961
|
|
|
@@ -3739,7 +2975,6 @@ const cutSelectedText = async editor => {
|
|
|
3739
2975
|
return scheduleDocumentAndCursorsSelections(editor, changes, selectionChanges);
|
|
3740
2976
|
};
|
|
3741
2977
|
|
|
3742
|
-
// @ts-ignore
|
|
3743
2978
|
const cut = editor => {
|
|
3744
2979
|
const {
|
|
3745
2980
|
selections
|
|
@@ -3999,12 +3234,94 @@ const format = async editor => {
|
|
|
3999
3234
|
}
|
|
4000
3235
|
};
|
|
4001
3236
|
|
|
3237
|
+
const RE_WORD_START$1 = /^[\w\-]+/;
|
|
3238
|
+
const RE_WORD_END$1 = /[\w\-]+$/;
|
|
3239
|
+
const getWordAt$1 = (line, columnIndex) => {
|
|
3240
|
+
const before = line.slice(0, columnIndex);
|
|
3241
|
+
const matchBefore = before.match(RE_WORD_END$1);
|
|
3242
|
+
const after = line.slice(columnIndex);
|
|
3243
|
+
const matchAfter = after.match(RE_WORD_START$1);
|
|
3244
|
+
let word = EmptyString;
|
|
3245
|
+
if (matchBefore) {
|
|
3246
|
+
word += matchBefore[0];
|
|
3247
|
+
}
|
|
3248
|
+
if (matchAfter) {
|
|
3249
|
+
word += matchAfter[0];
|
|
3250
|
+
}
|
|
3251
|
+
return {
|
|
3252
|
+
word
|
|
3253
|
+
};
|
|
3254
|
+
};
|
|
3255
|
+
const getWordBefore$1 = (line, columnIndex) => {
|
|
3256
|
+
const before = line.slice(0, columnIndex);
|
|
3257
|
+
const matchBefore = before.match(RE_WORD_END$1);
|
|
3258
|
+
if (matchBefore) {
|
|
3259
|
+
return matchBefore[0];
|
|
3260
|
+
}
|
|
3261
|
+
return EmptyString;
|
|
3262
|
+
};
|
|
3263
|
+
|
|
3264
|
+
const getWordAt = (editor, rowIndex, columnIndex) => {
|
|
3265
|
+
const {
|
|
3266
|
+
lines
|
|
3267
|
+
} = editor;
|
|
3268
|
+
const line = lines[rowIndex];
|
|
3269
|
+
return getWordAt$1(line, columnIndex);
|
|
3270
|
+
};
|
|
3271
|
+
const getWordBefore = (editor, rowIndex, columnIndex) => {
|
|
3272
|
+
const {
|
|
3273
|
+
lines
|
|
3274
|
+
} = editor;
|
|
3275
|
+
const line = lines[rowIndex];
|
|
3276
|
+
return getWordBefore$1(line, columnIndex);
|
|
3277
|
+
};
|
|
3278
|
+
|
|
4002
3279
|
// @ts-ignore
|
|
4003
3280
|
const getDefinition = async (editor, offset) => {
|
|
4004
3281
|
const definition = await invoke$3('ExtensionHostDefinition.executeDefinitionProvider', editor, offset);
|
|
4005
3282
|
return definition;
|
|
4006
3283
|
};
|
|
4007
3284
|
|
|
3285
|
+
const emptyObject = {};
|
|
3286
|
+
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
3287
|
+
const i18nString = (key, placeholders = emptyObject) => {
|
|
3288
|
+
if (placeholders === emptyObject) {
|
|
3289
|
+
return key;
|
|
3290
|
+
}
|
|
3291
|
+
const replacer = (match, rest) => {
|
|
3292
|
+
return placeholders[rest];
|
|
3293
|
+
};
|
|
3294
|
+
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
3295
|
+
};
|
|
3296
|
+
|
|
3297
|
+
const UiStrings = {
|
|
3298
|
+
GoToDefinition: 'Go to Definition',
|
|
3299
|
+
NoDefinitionFound: 'No definition found',
|
|
3300
|
+
NoDefinitionFoundFor: "No definition found for '{PH1}'",
|
|
3301
|
+
NoTypeDefinitionFound: 'No type definition found',
|
|
3302
|
+
NoTypeDefinitionFoundFor: "No type definition found for '{PH1}'",
|
|
3303
|
+
NoResults: 'No Results'
|
|
3304
|
+
};
|
|
3305
|
+
const noDefinitionFound = () => {
|
|
3306
|
+
return i18nString(UiStrings.NoDefinitionFound);
|
|
3307
|
+
};
|
|
3308
|
+
const noDefinitionFoundFor = word => {
|
|
3309
|
+
return i18nString(UiStrings.NoDefinitionFoundFor, {
|
|
3310
|
+
PH1: word
|
|
3311
|
+
});
|
|
3312
|
+
};
|
|
3313
|
+
const noTypeDefinitionFoundFor = word => {
|
|
3314
|
+
return i18nString(UiStrings.NoTypeDefinitionFoundFor, {
|
|
3315
|
+
PH1: word
|
|
3316
|
+
});
|
|
3317
|
+
};
|
|
3318
|
+
const noTypeDefinitionFound = () => {
|
|
3319
|
+
return i18nString(UiStrings.NoTypeDefinitionFound);
|
|
3320
|
+
};
|
|
3321
|
+
const noResults = () => {
|
|
3322
|
+
return i18nString(UiStrings.NoResults);
|
|
3323
|
+
};
|
|
3324
|
+
|
|
4008
3325
|
// @ts-ignore
|
|
4009
3326
|
const goTo = async ({
|
|
4010
3327
|
editor,
|
|
@@ -4834,7 +4151,7 @@ const handleTouchEnd = (editor, touchEvent) => {
|
|
|
4834
4151
|
|
|
4835
4152
|
// @ts-ignore
|
|
4836
4153
|
const setDeltaY = (editor, deltaY) => {
|
|
4837
|
-
return setDeltaY$
|
|
4154
|
+
return setDeltaY$1(editor, deltaY);
|
|
4838
4155
|
};
|
|
4839
4156
|
|
|
4840
4157
|
// @ts-ignore
|
|
@@ -5210,42 +4527,225 @@ const executeResolveCompletionItem = (editor, offset, name, completionItem) => {
|
|
|
5210
4527
|
});
|
|
5211
4528
|
};
|
|
5212
4529
|
|
|
5213
|
-
// TODO possible to do this with events/state machine instead of promises -> enables canceling operations / concurrent calls
|
|
5214
|
-
const getCompletions = async editor => {
|
|
5215
|
-
const {
|
|
5216
|
-
selections
|
|
5217
|
-
} = editor;
|
|
5218
|
-
const rowIndex = selections[0];
|
|
5219
|
-
const columnIndex = selections[1];
|
|
5220
|
-
// Editor.sync(editor)
|
|
5221
|
-
const offset = await offsetAt(editor, rowIndex, columnIndex);
|
|
5222
|
-
const completions = await executeCompletionProvider(editor, offset);
|
|
5223
|
-
return completions;
|
|
4530
|
+
// TODO possible to do this with events/state machine instead of promises -> enables canceling operations / concurrent calls
|
|
4531
|
+
const getCompletions = async editor => {
|
|
4532
|
+
const {
|
|
4533
|
+
selections
|
|
4534
|
+
} = editor;
|
|
4535
|
+
const rowIndex = selections[0];
|
|
4536
|
+
const columnIndex = selections[1];
|
|
4537
|
+
// Editor.sync(editor)
|
|
4538
|
+
const offset = await offsetAt(editor, rowIndex, columnIndex);
|
|
4539
|
+
const completions = await executeCompletionProvider(editor, offset);
|
|
4540
|
+
return completions;
|
|
4541
|
+
};
|
|
4542
|
+
|
|
4543
|
+
// TODO don't send unnecessary parts of completion item like matches
|
|
4544
|
+
const resolveCompletion = async (editor, name, completionItem) => {
|
|
4545
|
+
try {
|
|
4546
|
+
object(editor);
|
|
4547
|
+
string(name);
|
|
4548
|
+
object(completionItem);
|
|
4549
|
+
const rowIndex = editor.selections[0];
|
|
4550
|
+
const columnIndex = editor.selections[1];
|
|
4551
|
+
const offset = await offsetAt(editor, rowIndex, columnIndex);
|
|
4552
|
+
// @ts-ignore
|
|
4553
|
+
const resolvedCompletionItem = await executeResolveCompletionItem(editor, offset, name, completionItem);
|
|
4554
|
+
return resolvedCompletionItem;
|
|
4555
|
+
} catch {
|
|
4556
|
+
return undefined;
|
|
4557
|
+
}
|
|
4558
|
+
};
|
|
4559
|
+
|
|
4560
|
+
const None$1 = 1;
|
|
4561
|
+
|
|
4562
|
+
const EmptyMatches = [];
|
|
4563
|
+
|
|
4564
|
+
const Diagonal = 1;
|
|
4565
|
+
const Left = 2;
|
|
4566
|
+
|
|
4567
|
+
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
4568
|
+
|
|
4569
|
+
const createTable = size => {
|
|
4570
|
+
const table = [];
|
|
4571
|
+
for (let i = 0; i < size; i++) {
|
|
4572
|
+
const row = new Uint8Array(size);
|
|
4573
|
+
table.push(row);
|
|
4574
|
+
}
|
|
4575
|
+
return table;
|
|
4576
|
+
};
|
|
4577
|
+
|
|
4578
|
+
const isLowerCase = char => {
|
|
4579
|
+
return char === char.toLowerCase();
|
|
4580
|
+
};
|
|
4581
|
+
|
|
4582
|
+
const isUpperCase = char => {
|
|
4583
|
+
return char === char.toUpperCase();
|
|
4584
|
+
};
|
|
4585
|
+
|
|
4586
|
+
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
4587
|
+
const isGap = (columnCharBefore, columnChar) => {
|
|
4588
|
+
switch (columnCharBefore) {
|
|
4589
|
+
case Dash:
|
|
4590
|
+
case Underline:
|
|
4591
|
+
case EmptyString:
|
|
4592
|
+
case T:
|
|
4593
|
+
case Space:
|
|
4594
|
+
case Dot:
|
|
4595
|
+
return true;
|
|
4596
|
+
}
|
|
4597
|
+
if (isLowerCase(columnCharBefore) && isUpperCase(columnChar)) {
|
|
4598
|
+
return true;
|
|
4599
|
+
}
|
|
4600
|
+
return false;
|
|
4601
|
+
};
|
|
4602
|
+
|
|
4603
|
+
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
4604
|
+
const getScore = (rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, column, wordLength, isDiagonalMatch) => {
|
|
4605
|
+
if (rowCharLow !== columnCharLow) {
|
|
4606
|
+
return -1;
|
|
4607
|
+
}
|
|
4608
|
+
const isMatch = rowChar === columnChar;
|
|
4609
|
+
if (isMatch) {
|
|
4610
|
+
if (isDiagonalMatch) {
|
|
4611
|
+
return 8;
|
|
4612
|
+
}
|
|
4613
|
+
if (isGap(columnCharBefore, columnChar)) {
|
|
4614
|
+
return 8;
|
|
4615
|
+
}
|
|
4616
|
+
return 5;
|
|
4617
|
+
}
|
|
4618
|
+
if (isGap(columnCharBefore, columnChar)) {
|
|
4619
|
+
return 8;
|
|
4620
|
+
}
|
|
4621
|
+
return 5;
|
|
4622
|
+
};
|
|
4623
|
+
|
|
4624
|
+
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
4625
|
+
|
|
4626
|
+
const isPatternInWord = (patternLow, patternPos, patternLen, wordLow, wordPos, wordLen) => {
|
|
4627
|
+
while (patternPos < patternLen && wordPos < wordLen) {
|
|
4628
|
+
if (patternLow[patternPos] === wordLow[wordPos]) {
|
|
4629
|
+
patternPos += 1;
|
|
4630
|
+
}
|
|
4631
|
+
wordPos += 1;
|
|
4632
|
+
}
|
|
4633
|
+
return patternPos === patternLen; // pattern must be exhausted
|
|
4634
|
+
};
|
|
4635
|
+
|
|
4636
|
+
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
4637
|
+
const traceHighlights = (table, arrows, patternLength, wordLength) => {
|
|
4638
|
+
let row = patternLength;
|
|
4639
|
+
let column = wordLength;
|
|
4640
|
+
const matches = [];
|
|
4641
|
+
while (row >= 1 && column >= 1) {
|
|
4642
|
+
const arrow = arrows[row][column];
|
|
4643
|
+
if (arrow === Left) {
|
|
4644
|
+
column--;
|
|
4645
|
+
} else if (arrow === Diagonal) {
|
|
4646
|
+
row--;
|
|
4647
|
+
column--;
|
|
4648
|
+
const start = column + 1;
|
|
4649
|
+
while (row >= 1 && column >= 1) {
|
|
4650
|
+
const arrow = arrows[row][column];
|
|
4651
|
+
if (arrow === Left) {
|
|
4652
|
+
break;
|
|
4653
|
+
}
|
|
4654
|
+
if (arrow === Diagonal) {
|
|
4655
|
+
row--;
|
|
4656
|
+
column--;
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
const end = column;
|
|
4660
|
+
matches.unshift(end, start);
|
|
4661
|
+
}
|
|
4662
|
+
}
|
|
4663
|
+
matches.unshift(table[patternLength][wordLength - 1]);
|
|
4664
|
+
return matches;
|
|
5224
4665
|
};
|
|
5225
4666
|
|
|
5226
|
-
//
|
|
5227
|
-
const
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
4667
|
+
// based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
|
|
4668
|
+
const gridSize = 128;
|
|
4669
|
+
const table = createTable(gridSize);
|
|
4670
|
+
const arrows = createTable(gridSize);
|
|
4671
|
+
const filterCompletionItem = (pattern, word) => {
|
|
4672
|
+
const patternLength = Math.min(pattern.length, gridSize - 1);
|
|
4673
|
+
const wordLength = Math.min(word.length, gridSize - 1);
|
|
4674
|
+
const patternLower = pattern.toLowerCase();
|
|
4675
|
+
const wordLower = word.toLowerCase();
|
|
4676
|
+
if (!isPatternInWord(patternLower, 0, patternLength, wordLower, 0, wordLength)) {
|
|
4677
|
+
return EmptyMatches;
|
|
4678
|
+
}
|
|
4679
|
+
let strongMatch = false;
|
|
4680
|
+
for (let row = 1; row < patternLength + 1; row++) {
|
|
4681
|
+
const rowChar = pattern[row - 1];
|
|
4682
|
+
const rowCharLow = patternLower[row - 1];
|
|
4683
|
+
for (let column = 1; column < wordLength + 1; column++) {
|
|
4684
|
+
const columnChar = word[column - 1];
|
|
4685
|
+
const columnCharLow = wordLower[column - 1];
|
|
4686
|
+
const columnCharBefore = word[column - 2] || '';
|
|
4687
|
+
const isDiagonalMatch = arrows[row - 1][column - 1] === Diagonal;
|
|
4688
|
+
const score = getScore(rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, column, wordLength, isDiagonalMatch);
|
|
4689
|
+
if (row === 1 && score > 5) {
|
|
4690
|
+
strongMatch = true;
|
|
4691
|
+
}
|
|
4692
|
+
let diagonalScore = score + table[row - 1][column - 1];
|
|
4693
|
+
if (isDiagonalMatch && score !== -1) {
|
|
4694
|
+
diagonalScore += 2;
|
|
4695
|
+
}
|
|
4696
|
+
const leftScore = table[row][column - 1];
|
|
4697
|
+
if (leftScore > diagonalScore) {
|
|
4698
|
+
table[row][column] = leftScore;
|
|
4699
|
+
arrows[row][column] = Left;
|
|
4700
|
+
} else {
|
|
4701
|
+
table[row][column] = diagonalScore;
|
|
4702
|
+
arrows[row][column] = Diagonal;
|
|
4703
|
+
}
|
|
4704
|
+
}
|
|
4705
|
+
}
|
|
4706
|
+
if (!strongMatch) {
|
|
4707
|
+
return EmptyMatches;
|
|
5240
4708
|
}
|
|
4709
|
+
const highlights = traceHighlights(table, arrows, patternLength, wordLength);
|
|
4710
|
+
return highlights;
|
|
5241
4711
|
};
|
|
5242
4712
|
|
|
5243
|
-
const
|
|
4713
|
+
const Deprecated = 1 << 0;
|
|
5244
4714
|
|
|
5245
|
-
const
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
4715
|
+
const addEmptyMatch = item => {
|
|
4716
|
+
return {
|
|
4717
|
+
...item,
|
|
4718
|
+
matches: EmptyMatches
|
|
4719
|
+
};
|
|
4720
|
+
};
|
|
4721
|
+
const filterCompletionItems = (completionItems, word) => {
|
|
4722
|
+
if (word === EmptyString) {
|
|
4723
|
+
return completionItems.map(addEmptyMatch);
|
|
4724
|
+
}
|
|
4725
|
+
const filteredCompletions = [];
|
|
4726
|
+
const deprecated = [];
|
|
4727
|
+
for (const completionItem of completionItems) {
|
|
4728
|
+
const {
|
|
4729
|
+
label,
|
|
4730
|
+
flags
|
|
4731
|
+
} = completionItem;
|
|
4732
|
+
const result = filterCompletionItem(word, label);
|
|
4733
|
+
if (result !== EmptyMatches) {
|
|
4734
|
+
if (flags & Deprecated) {
|
|
4735
|
+
// TODO avoid mutation
|
|
4736
|
+
completionItem.matches = EmptyMatches;
|
|
4737
|
+
deprecated.push(completionItem);
|
|
4738
|
+
} else {
|
|
4739
|
+
// TODO avoid mutation
|
|
4740
|
+
completionItem.matches = result;
|
|
4741
|
+
filteredCompletions.push(completionItem);
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4745
|
+
if (deprecated.length > 0) {
|
|
4746
|
+
filteredCompletions.push(...deprecated);
|
|
4747
|
+
}
|
|
4748
|
+
return filteredCompletions;
|
|
5249
4749
|
};
|
|
5250
4750
|
|
|
5251
4751
|
const getEditor = editorUid => {
|
|
@@ -5259,6 +4759,23 @@ const getEditor = editorUid => {
|
|
|
5259
4759
|
return newState;
|
|
5260
4760
|
};
|
|
5261
4761
|
|
|
4762
|
+
const getFinalDeltaY = (height, itemHeight, itemsLength) => {
|
|
4763
|
+
const contentHeight = itemsLength * itemHeight;
|
|
4764
|
+
const finalDeltaY = Math.max(contentHeight - height, 0);
|
|
4765
|
+
return finalDeltaY;
|
|
4766
|
+
};
|
|
4767
|
+
|
|
4768
|
+
const getListHeight = (itemsLength, itemHeight, maxHeight) => {
|
|
4769
|
+
number$1(itemsLength);
|
|
4770
|
+
number$1(itemHeight);
|
|
4771
|
+
number$1(maxHeight);
|
|
4772
|
+
if (itemsLength === 0) {
|
|
4773
|
+
return itemHeight;
|
|
4774
|
+
}
|
|
4775
|
+
const totalHeight = itemsLength * itemHeight;
|
|
4776
|
+
return Math.min(totalHeight, maxHeight);
|
|
4777
|
+
};
|
|
4778
|
+
|
|
5262
4779
|
const RE_WORD = /[\w\-]+$/;
|
|
5263
4780
|
const getWordAtOffset = editor => {
|
|
5264
4781
|
const {
|
|
@@ -5275,7 +4792,7 @@ const getWordAtOffset = editor => {
|
|
|
5275
4792
|
}
|
|
5276
4793
|
return '';
|
|
5277
4794
|
};
|
|
5278
|
-
const handleEditorType = (editorUid, state, text) => {
|
|
4795
|
+
const handleEditorType$1 = (editorUid, state, text) => {
|
|
5279
4796
|
const editor = getEditor(editorUid);
|
|
5280
4797
|
const {
|
|
5281
4798
|
unfilteredItems,
|
|
@@ -5305,7 +4822,7 @@ const handleEditorType = (editorUid, state, text) => {
|
|
|
5305
4822
|
finalDeltaY
|
|
5306
4823
|
};
|
|
5307
4824
|
};
|
|
5308
|
-
const handleEditorDeleteLeft = (editorUid, state) => {
|
|
4825
|
+
const handleEditorDeleteLeft$1 = (editorUid, state) => {
|
|
5309
4826
|
const editor = getEditor(editorUid);
|
|
5310
4827
|
const {
|
|
5311
4828
|
unfilteredItems,
|
|
@@ -5319,7 +4836,7 @@ const handleEditorDeleteLeft = (editorUid, state) => {
|
|
|
5319
4836
|
const y$1 = y(editor, rowIndex);
|
|
5320
4837
|
const wordAtOffset = getWordAtOffset(editor);
|
|
5321
4838
|
if (!wordAtOffset) {
|
|
5322
|
-
editor.completionState = None;
|
|
4839
|
+
editor.completionState = None$1;
|
|
5323
4840
|
return {
|
|
5324
4841
|
...state,
|
|
5325
4842
|
disposed: true
|
|
@@ -5345,7 +4862,7 @@ const dispose = state => {
|
|
|
5345
4862
|
};
|
|
5346
4863
|
};
|
|
5347
4864
|
const disposeWithEditor = (state, editor) => {
|
|
5348
|
-
editor.completionState = None;
|
|
4865
|
+
editor.completionState = None$1;
|
|
5349
4866
|
editor.completionUid = 0;
|
|
5350
4867
|
// Focus.removeAdditionalFocus(FocusKey.EditorCompletion)
|
|
5351
4868
|
return dispose(state);
|
|
@@ -5399,14 +4916,26 @@ const advance = (state, word) => {
|
|
|
5399
4916
|
};
|
|
5400
4917
|
};
|
|
5401
4918
|
|
|
4919
|
+
const hasWidget = (widgets, id) => {
|
|
4920
|
+
for (const widget of widgets) {
|
|
4921
|
+
if (widget.id === id) {
|
|
4922
|
+
return true;
|
|
4923
|
+
}
|
|
4924
|
+
}
|
|
4925
|
+
return false;
|
|
4926
|
+
};
|
|
4927
|
+
|
|
5402
4928
|
const openCompletion = async editor => {
|
|
5403
4929
|
const {
|
|
5404
4930
|
widgets,
|
|
5405
4931
|
uid
|
|
5406
4932
|
} = editor;
|
|
4933
|
+
if (hasWidget(widgets, Completion)) {
|
|
4934
|
+
return editor;
|
|
4935
|
+
}
|
|
5407
4936
|
const completionUid = Math.random();
|
|
5408
4937
|
const completionWidget = {
|
|
5409
|
-
id:
|
|
4938
|
+
id: Completion,
|
|
5410
4939
|
oldState: {
|
|
5411
4940
|
items: [],
|
|
5412
4941
|
itemHeight: 20,
|
|
@@ -5675,11 +5204,8 @@ const editorSelectAllLeft = editor => {
|
|
|
5675
5204
|
editorSelectHorizontalLeft(editor, lineCharacterStart);
|
|
5676
5205
|
};
|
|
5677
5206
|
|
|
5678
|
-
// @ts-ignore
|
|
5679
|
-
|
|
5680
5207
|
// TODO handle virtual space
|
|
5681
5208
|
|
|
5682
|
-
// @ts-ignore
|
|
5683
5209
|
const getNewSelectionsSingleLineWord = (lines, word) => {
|
|
5684
5210
|
if (word.length === 0) {
|
|
5685
5211
|
throw new Error('word length must be greater than zero');
|
|
@@ -5694,8 +5220,6 @@ const getNewSelectionsSingleLineWord = (lines, word) => {
|
|
|
5694
5220
|
}
|
|
5695
5221
|
return new Uint32Array(newSelections);
|
|
5696
5222
|
};
|
|
5697
|
-
|
|
5698
|
-
// @ts-ignore
|
|
5699
5223
|
const isMultiLineMatch = (lines, rowIndex, wordParts) => {
|
|
5700
5224
|
let j = 0;
|
|
5701
5225
|
if (!lines[rowIndex + j].endsWith(wordParts[j])) {
|
|
@@ -5716,11 +5240,11 @@ const isMultiLineMatch = (lines, rowIndex, wordParts) => {
|
|
|
5716
5240
|
|
|
5717
5241
|
// TODO this is very expensive, there might be a better algorithm for this
|
|
5718
5242
|
// TODO if this matches the given selections, don't schedule selections/rerender
|
|
5719
|
-
// @ts-ignore
|
|
5720
5243
|
const getAllOccurrencesMultiLine = (lines, wordParts) => {
|
|
5721
5244
|
const newSelections = [];
|
|
5722
5245
|
for (let rowIndex = 0; rowIndex < lines.length - wordParts.length + 1; rowIndex) {
|
|
5723
5246
|
if (isMultiLineMatch(lines, rowIndex, wordParts)) {
|
|
5247
|
+
// @ts-ignore
|
|
5724
5248
|
newSelections.push(rowIndex, lines[rowIndex].length - wordParts[0].length, rowIndex + wordParts.length - 1, wordParts.at(-1).length);
|
|
5725
5249
|
rowIndex += wordParts.length - 1;
|
|
5726
5250
|
} else {
|
|
@@ -5732,13 +5256,9 @@ const getAllOccurrencesMultiLine = (lines, wordParts) => {
|
|
|
5732
5256
|
|
|
5733
5257
|
// TODO duplicate code with EditorSelectNextOccurrence
|
|
5734
5258
|
const RE_ALPHA_NUMERIC$1 = /[a-zA-Z\d]/;
|
|
5735
|
-
|
|
5736
|
-
// @ts-ignore
|
|
5737
5259
|
const isAlphaNumeric$1 = char => {
|
|
5738
5260
|
return RE_ALPHA_NUMERIC$1.test(char);
|
|
5739
5261
|
};
|
|
5740
|
-
|
|
5741
|
-
// @ts-ignore
|
|
5742
5262
|
const getWordStartIndex$1 = (line, index) => {
|
|
5743
5263
|
for (let i = index - 1; i >= 0; i--) {
|
|
5744
5264
|
if (!isAlphaNumeric$1(line[i])) {
|
|
@@ -5747,8 +5267,6 @@ const getWordStartIndex$1 = (line, index) => {
|
|
|
5747
5267
|
}
|
|
5748
5268
|
return 0;
|
|
5749
5269
|
};
|
|
5750
|
-
|
|
5751
|
-
// @ts-ignore
|
|
5752
5270
|
const getWordEndIndex$1 = (line, index) => {
|
|
5753
5271
|
for (let i = index; i < line.length; i++) {
|
|
5754
5272
|
if (!isAlphaNumeric$1(line[i])) {
|
|
@@ -5757,8 +5275,6 @@ const getWordEndIndex$1 = (line, index) => {
|
|
|
5757
5275
|
}
|
|
5758
5276
|
return line.length - 1;
|
|
5759
5277
|
};
|
|
5760
|
-
|
|
5761
|
-
// @ts-ignore
|
|
5762
5278
|
const getWordMatchAtPosition$1 = (lines, rowIndex, columnIndex) => {
|
|
5763
5279
|
const line = lines[rowIndex];
|
|
5764
5280
|
const start = getWordStartIndex$1(line, columnIndex);
|
|
@@ -5770,8 +5286,6 @@ const getWordMatchAtPosition$1 = (lines, rowIndex, columnIndex) => {
|
|
|
5770
5286
|
word
|
|
5771
5287
|
};
|
|
5772
5288
|
};
|
|
5773
|
-
|
|
5774
|
-
// @ts-ignore
|
|
5775
5289
|
const getNewSelections$3 = (lines, selections) => {
|
|
5776
5290
|
if (selections.length < 4) {
|
|
5777
5291
|
throw new Error('selections must have at least one entry');
|
|
@@ -5804,12 +5318,12 @@ const getNewSelections$3 = (lines, selections) => {
|
|
|
5804
5318
|
const newSelections = getAllOccurrencesMultiLine(lines, wordParts);
|
|
5805
5319
|
return newSelections;
|
|
5806
5320
|
};
|
|
5807
|
-
|
|
5808
|
-
// @ts-ignore
|
|
5809
5321
|
const selectAllOccurrences = editor => {
|
|
5810
5322
|
// when there are no selections -> first selection is word -> find all selection that include word
|
|
5811
|
-
const
|
|
5812
|
-
|
|
5323
|
+
const {
|
|
5324
|
+
lines,
|
|
5325
|
+
selections
|
|
5326
|
+
} = editor;
|
|
5813
5327
|
const newSelections = getNewSelections$3(lines, selections);
|
|
5814
5328
|
return scheduleSelections(editor, newSelections);
|
|
5815
5329
|
};
|
|
@@ -6377,7 +5891,6 @@ const showSourceActions = async editor => {
|
|
|
6377
5891
|
return editor;
|
|
6378
5892
|
};
|
|
6379
5893
|
|
|
6380
|
-
// @ts-ignore
|
|
6381
5894
|
const compareString = (a, b) => {
|
|
6382
5895
|
return a.localeCompare(b);
|
|
6383
5896
|
};
|
|
@@ -7162,7 +6675,7 @@ const editorUnindent = editor => {
|
|
|
7162
6675
|
// editor.lines //?
|
|
7163
6676
|
|
|
7164
6677
|
const isCompletion$2 = widget => {
|
|
7165
|
-
return widget.id ===
|
|
6678
|
+
return widget.id === Completion;
|
|
7166
6679
|
};
|
|
7167
6680
|
const getCompletionState = editor => {
|
|
7168
6681
|
const {
|
|
@@ -7173,7 +6686,7 @@ const getCompletionState = editor => {
|
|
|
7173
6686
|
};
|
|
7174
6687
|
|
|
7175
6688
|
const isCompletion$1 = widget => {
|
|
7176
|
-
return widget.id ===
|
|
6689
|
+
return widget.id === Completion;
|
|
7177
6690
|
};
|
|
7178
6691
|
const focusIndex$1 = (editor, index) => {
|
|
7179
6692
|
const child = getCompletionState(editor);
|
|
@@ -7236,7 +6749,7 @@ const getEdits = async (editor, completionItem) => {
|
|
|
7236
6749
|
return changes;
|
|
7237
6750
|
};
|
|
7238
6751
|
const isCompletion = widget => {
|
|
7239
|
-
return widget.id ===
|
|
6752
|
+
return widget.id === Completion;
|
|
7240
6753
|
};
|
|
7241
6754
|
const select = async (editor, completionItem) => {
|
|
7242
6755
|
const changes = await getEdits(editor, completionItem);
|
|
@@ -7245,7 +6758,7 @@ const select = async (editor, completionItem) => {
|
|
|
7245
6758
|
();
|
|
7246
6759
|
if (index !== -1) {
|
|
7247
6760
|
editor.widgets.splice(index, 1);
|
|
7248
|
-
editor.completionState = None;
|
|
6761
|
+
editor.completionState = None$1;
|
|
7249
6762
|
editor.completionUid = 0;
|
|
7250
6763
|
}
|
|
7251
6764
|
// TODO dispose completion widget
|
|
@@ -7308,7 +6821,7 @@ const getHover = async (editor, offset) => {
|
|
|
7308
6821
|
|
|
7309
6822
|
let _ipc;
|
|
7310
6823
|
const listen$5 = async () => {
|
|
7311
|
-
const ipc = await create({
|
|
6824
|
+
const ipc = await create$1({
|
|
7312
6825
|
method: RendererProcess
|
|
7313
6826
|
});
|
|
7314
6827
|
handleIpc(ipc);
|
|
@@ -7537,6 +7050,14 @@ const handleSashPointerUp = (state, eventX, eventY) => {
|
|
|
7537
7050
|
return state;
|
|
7538
7051
|
};
|
|
7539
7052
|
|
|
7053
|
+
const text = data => {
|
|
7054
|
+
return {
|
|
7055
|
+
type: Text,
|
|
7056
|
+
text: data,
|
|
7057
|
+
childCount: 0
|
|
7058
|
+
};
|
|
7059
|
+
};
|
|
7060
|
+
|
|
7540
7061
|
const getLineInfoVirtualDom = lineInfo => {
|
|
7541
7062
|
const dom = [{
|
|
7542
7063
|
type: Div,
|
|
@@ -7624,7 +7145,7 @@ const renderHoverDom = {
|
|
|
7624
7145
|
return [/* method */'Viewlet.setDom2', dom];
|
|
7625
7146
|
}
|
|
7626
7147
|
};
|
|
7627
|
-
const renderBounds = {
|
|
7148
|
+
const renderBounds$1 = {
|
|
7628
7149
|
isEqual(oldState, newState) {
|
|
7629
7150
|
return oldState.x === newState.x && oldState.y === newState.y && oldState.resizedWidth === newState.resizedWidth;
|
|
7630
7151
|
},
|
|
@@ -7642,10 +7163,10 @@ const renderBounds = {
|
|
|
7642
7163
|
return [SetBounds, x, y, resizedWidth, height];
|
|
7643
7164
|
}
|
|
7644
7165
|
};
|
|
7645
|
-
const render$
|
|
7166
|
+
const render$3 = [renderHoverDom, renderBounds$1];
|
|
7646
7167
|
const renderHover = async (oldState, newState) => {
|
|
7647
7168
|
const commands = [];
|
|
7648
|
-
for (const item of render$
|
|
7169
|
+
for (const item of render$3) {
|
|
7649
7170
|
if (!item.isEqual(oldState, newState)) {
|
|
7650
7171
|
commands.push(item.apply(oldState, newState));
|
|
7651
7172
|
}
|
|
@@ -7951,7 +7472,7 @@ const moveLineUp = editor => {
|
|
|
7951
7472
|
};
|
|
7952
7473
|
|
|
7953
7474
|
const Link$1 = 'Link';
|
|
7954
|
-
const Function = 'Function';
|
|
7475
|
+
const Function$1 = 'Function';
|
|
7955
7476
|
const Parameter = 'Parameter';
|
|
7956
7477
|
const Type = 'Type';
|
|
7957
7478
|
const VariableName = 'VariableName';
|
|
@@ -8010,7 +7531,7 @@ const getDecorationClassName = type => {
|
|
|
8010
7531
|
case Ts3073:
|
|
8011
7532
|
case Ts3077:
|
|
8012
7533
|
case Ts3088:
|
|
8013
|
-
return Function;
|
|
7534
|
+
return Function$1;
|
|
8014
7535
|
case Ts1792:
|
|
8015
7536
|
case Ts1793:
|
|
8016
7537
|
return Parameter;
|
|
@@ -8262,14 +7783,86 @@ const getLineInfoEmbeddedFull = (embeddedResults, tokenResults, line, normalize,
|
|
|
8262
7783
|
startIndex,
|
|
8263
7784
|
start,
|
|
8264
7785
|
end
|
|
8265
|
-
} = getStartDefaults(embeddedTokens, minOffset);
|
|
7786
|
+
} = getStartDefaults(embeddedTokens, minOffset);
|
|
7787
|
+
const difference = getDifference(start, averageCharWidth, deltaX);
|
|
7788
|
+
for (let i = startIndex; i < tokensLength; i += 2) {
|
|
7789
|
+
const tokenType = embeddedTokens[i];
|
|
7790
|
+
const tokenLength = embeddedTokens[i + 1];
|
|
7791
|
+
end += tokenLength;
|
|
7792
|
+
const className = `Token ${embeddedTokenMap[tokenType] || 'Unknown'}`;
|
|
7793
|
+
const text = line.slice(start, end);
|
|
7794
|
+
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
7795
|
+
lineInfo.push(normalizedText, className);
|
|
7796
|
+
start = end;
|
|
7797
|
+
if (end >= maxOffset) {
|
|
7798
|
+
break;
|
|
7799
|
+
}
|
|
7800
|
+
}
|
|
7801
|
+
return {
|
|
7802
|
+
lineInfo,
|
|
7803
|
+
difference
|
|
7804
|
+
};
|
|
7805
|
+
};
|
|
7806
|
+
const getOffsets = (deltaX, width, averageCharWidth) => {
|
|
7807
|
+
// TODO accurately measure char widths using offscreen canvas
|
|
7808
|
+
// and use fast measurements for monospace ascii text
|
|
7809
|
+
if (deltaX === 0) {
|
|
7810
|
+
return {
|
|
7811
|
+
minOffset: 0,
|
|
7812
|
+
maxOffset: Math.ceil(width / averageCharWidth)
|
|
7813
|
+
};
|
|
7814
|
+
}
|
|
7815
|
+
const minOffset = Math.ceil(deltaX / averageCharWidth);
|
|
7816
|
+
const maxOffset = minOffset + Math.ceil(width / averageCharWidth);
|
|
7817
|
+
return {
|
|
7818
|
+
minOffset,
|
|
7819
|
+
maxOffset
|
|
7820
|
+
};
|
|
7821
|
+
};
|
|
7822
|
+
const getDifference = (start, averageCharWidth, deltaX) => {
|
|
7823
|
+
const beforeWidth = start * averageCharWidth;
|
|
7824
|
+
const difference = beforeWidth - deltaX;
|
|
7825
|
+
return difference;
|
|
7826
|
+
};
|
|
7827
|
+
const getLineInfoDefault = (line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset) => {
|
|
7828
|
+
const lineInfo = [];
|
|
7829
|
+
let decorationIndex = 0;
|
|
7830
|
+
for (; decorationIndex < decorations.length; decorationIndex += 3) {
|
|
7831
|
+
const decorationOffset = decorations[decorationIndex];
|
|
7832
|
+
if (decorationOffset >= lineOffset) {
|
|
7833
|
+
break;
|
|
7834
|
+
}
|
|
7835
|
+
}
|
|
7836
|
+
const tokens = tokenResults.tokens;
|
|
7837
|
+
let {
|
|
7838
|
+
startIndex,
|
|
7839
|
+
start,
|
|
7840
|
+
end
|
|
7841
|
+
} = getStartDefaults(tokens, minOffset);
|
|
8266
7842
|
const difference = getDifference(start, averageCharWidth, deltaX);
|
|
7843
|
+
const tokensLength = tokens.length;
|
|
8267
7844
|
for (let i = startIndex; i < tokensLength; i += 2) {
|
|
8268
|
-
const tokenType =
|
|
8269
|
-
const tokenLength =
|
|
7845
|
+
const tokenType = tokens[i];
|
|
7846
|
+
const tokenLength = tokens[i + 1];
|
|
7847
|
+
const decorationOffset = decorations[decorationIndex];
|
|
7848
|
+
let extraClassName = '';
|
|
7849
|
+
if (decorationOffset !== undefined && decorationOffset - lineOffset === start) {
|
|
7850
|
+
// @ts-ignore
|
|
7851
|
+
decorations[++decorationIndex];
|
|
7852
|
+
const decorationType = decorations[++decorationIndex];
|
|
7853
|
+
// @ts-ignore
|
|
7854
|
+
decorations[++decorationIndex];
|
|
7855
|
+
// console.log('MATCHING DECORATION', {
|
|
7856
|
+
// decorationIndex,
|
|
7857
|
+
// decorationLength,
|
|
7858
|
+
// decorationType,
|
|
7859
|
+
// decorationModifiers,
|
|
7860
|
+
// })
|
|
7861
|
+
extraClassName = getDecorationClassName(decorationType);
|
|
7862
|
+
}
|
|
8270
7863
|
end += tokenLength;
|
|
8271
|
-
const className = `Token ${embeddedTokenMap[tokenType] || 'Unknown'}`;
|
|
8272
7864
|
const text = line.slice(start, end);
|
|
7865
|
+
const className = `Token ${extraClassName || TokenMap[tokenType] || 'Unknown'}`;
|
|
8273
7866
|
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
8274
7867
|
lineInfo.push(normalizedText, className);
|
|
8275
7868
|
start = end;
|
|
@@ -8282,285 +7875,564 @@ const getLineInfoEmbeddedFull = (embeddedResults, tokenResults, line, normalize,
|
|
|
8282
7875
|
difference
|
|
8283
7876
|
};
|
|
8284
7877
|
};
|
|
8285
|
-
const
|
|
8286
|
-
|
|
8287
|
-
|
|
8288
|
-
|
|
8289
|
-
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
7878
|
+
const getLineInfo = (line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth) => {
|
|
7879
|
+
const {
|
|
7880
|
+
minOffset,
|
|
7881
|
+
maxOffset
|
|
7882
|
+
} = getOffsets(deltaX, width, averageCharWidth);
|
|
7883
|
+
if (embeddedResults.length > 0 && tokenResults.embeddedResultIndex !== undefined) {
|
|
7884
|
+
const embeddedResult = embeddedResults[tokenResults.embeddedResultIndex];
|
|
7885
|
+
if (embeddedResult && embeddedResult.isFull) {
|
|
7886
|
+
return getLineInfoEmbeddedFull(embeddedResults, tokenResults, line, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
7887
|
+
}
|
|
7888
|
+
}
|
|
7889
|
+
return getLineInfoDefault(line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
7890
|
+
};
|
|
7891
|
+
|
|
7892
|
+
// TODO need lots of tests for this
|
|
7893
|
+
const getLineInfosViewport = (editor, tokens, embeddedResults, minLineY, maxLineY, minLineOffset, width, deltaX, averageCharWidth) => {
|
|
7894
|
+
const result = [];
|
|
7895
|
+
const differences = [];
|
|
7896
|
+
const {
|
|
7897
|
+
lines,
|
|
7898
|
+
decorations,
|
|
7899
|
+
languageId
|
|
7900
|
+
} = editor;
|
|
7901
|
+
const tokenMap = get$1(languageId);
|
|
7902
|
+
let offset = minLineOffset;
|
|
7903
|
+
const tabSize = 2;
|
|
7904
|
+
for (let i = minLineY; i < maxLineY; i++) {
|
|
7905
|
+
const line = lines[i];
|
|
7906
|
+
const normalize = shouldNormalizeText(line);
|
|
7907
|
+
const {
|
|
7908
|
+
lineInfo,
|
|
7909
|
+
difference
|
|
7910
|
+
} = getLineInfo(line, tokens[i - minLineY], embeddedResults, decorations, tokenMap, offset, normalize, tabSize, width, deltaX, averageCharWidth);
|
|
7911
|
+
result.push(lineInfo);
|
|
7912
|
+
differences.push(difference);
|
|
7913
|
+
offset += line.length + 1;
|
|
7914
|
+
}
|
|
7915
|
+
return {
|
|
7916
|
+
result,
|
|
7917
|
+
differences
|
|
7918
|
+
};
|
|
7919
|
+
};
|
|
7920
|
+
const getVisible = async (editor, syncIncremental) => {
|
|
7921
|
+
// console.log({ editor })
|
|
7922
|
+
// TODO should separate rendering from business logic somehow
|
|
7923
|
+
// currently hard to test because need to mock editor height, top, left,
|
|
7924
|
+
// invalidStartIndex, lineCache, etc. just for testing editorType
|
|
7925
|
+
// editor.invalidStartIndex = changes[0].start.rowIndex
|
|
7926
|
+
// @ts-ignore
|
|
7927
|
+
const {
|
|
7928
|
+
minLineY,
|
|
7929
|
+
numberOfVisibleLines,
|
|
7930
|
+
lines,
|
|
7931
|
+
width,
|
|
7932
|
+
deltaX,
|
|
7933
|
+
fontWeight,
|
|
7934
|
+
fontSize,
|
|
7935
|
+
fontFamily,
|
|
7936
|
+
letterSpacing,
|
|
7937
|
+
charWidth
|
|
7938
|
+
} = editor;
|
|
7939
|
+
const maxLineY = Math.min(minLineY + numberOfVisibleLines, lines.length);
|
|
7940
|
+
const {
|
|
7941
|
+
tokens,
|
|
7942
|
+
tokenizersToLoad,
|
|
7943
|
+
embeddedResults
|
|
7944
|
+
} = await getTokensViewport2(editor, minLineY, maxLineY, syncIncremental);
|
|
7945
|
+
const minLineOffset = offsetAtSync(editor, minLineY, 0);
|
|
7946
|
+
const averageCharWidth = charWidth;
|
|
7947
|
+
const {
|
|
7948
|
+
result,
|
|
7949
|
+
differences
|
|
7950
|
+
} = getLineInfosViewport(editor, tokens, embeddedResults, minLineY, maxLineY, minLineOffset, width, deltaX, averageCharWidth);
|
|
7951
|
+
if (tokenizersToLoad.length > 0) {
|
|
7952
|
+
loadTokenizers(tokenizersToLoad);
|
|
7953
|
+
}
|
|
7954
|
+
return {
|
|
7955
|
+
textInfos: result,
|
|
7956
|
+
differences
|
|
7957
|
+
};
|
|
7958
|
+
};
|
|
7959
|
+
|
|
7960
|
+
const getCursorsVirtualDom = cursors => {
|
|
7961
|
+
const dom = [];
|
|
7962
|
+
for (const translate of cursors) {
|
|
7963
|
+
dom.push({
|
|
7964
|
+
type: Div,
|
|
7965
|
+
className: EditorCursor,
|
|
7966
|
+
translate
|
|
7967
|
+
});
|
|
7968
|
+
}
|
|
7969
|
+
return dom;
|
|
7970
|
+
};
|
|
7971
|
+
|
|
7972
|
+
const Error$1 = 'error';
|
|
7973
|
+
const Warning = 'warning';
|
|
7974
|
+
|
|
7975
|
+
const getDiagnosticClassName = type => {
|
|
7976
|
+
// TODO use classnames enum
|
|
7977
|
+
switch (type) {
|
|
7978
|
+
case Error$1:
|
|
7979
|
+
return 'DiagnosticError';
|
|
7980
|
+
case Warning:
|
|
7981
|
+
return 'DiagnosticWarning';
|
|
7982
|
+
default:
|
|
7983
|
+
return 'DiagnosticError';
|
|
7984
|
+
}
|
|
7985
|
+
};
|
|
7986
|
+
const getDiagnosticVirtualDom = diagnostic => {
|
|
7987
|
+
const {
|
|
7988
|
+
x,
|
|
7989
|
+
y,
|
|
7990
|
+
width,
|
|
7991
|
+
height,
|
|
7992
|
+
type
|
|
7993
|
+
} = diagnostic;
|
|
7994
|
+
const extraClassName = getDiagnosticClassName(type);
|
|
7995
|
+
return [{
|
|
7996
|
+
type: Div,
|
|
7997
|
+
className: `${Diagnostic} ${extraClassName}`,
|
|
7998
|
+
width,
|
|
7999
|
+
height,
|
|
8000
|
+
top: y,
|
|
8001
|
+
left: x,
|
|
8002
|
+
childCount: 0
|
|
8003
|
+
}];
|
|
8004
|
+
};
|
|
8005
|
+
|
|
8006
|
+
const getDiagnosticsVirtualDom = diagnostics => {
|
|
8007
|
+
const dom = diagnostics.flatMap(getDiagnosticVirtualDom);
|
|
8008
|
+
return dom;
|
|
8009
|
+
};
|
|
8010
|
+
|
|
8011
|
+
const getGutterInfoVirtualDom = gutterInfo => {
|
|
8012
|
+
return [{
|
|
8013
|
+
type: Span,
|
|
8014
|
+
className: 'LineNumber',
|
|
8015
|
+
childCount: 1
|
|
8016
|
+
}, text(gutterInfo)];
|
|
8017
|
+
};
|
|
8018
|
+
const getEditorGutterVirtualDom = gutterInfos => {
|
|
8019
|
+
const dom = gutterInfos.flatMap(getGutterInfoVirtualDom);
|
|
8020
|
+
return dom;
|
|
8021
|
+
};
|
|
8022
|
+
|
|
8023
|
+
const getEditorRowsVirtualDom = (textInfos, differences, lineNumbers = true) => {
|
|
8024
|
+
const dom = [];
|
|
8025
|
+
for (let i = 0; i < textInfos.length; i++) {
|
|
8026
|
+
const textInfo = textInfos[i];
|
|
8027
|
+
const difference = differences[i];
|
|
8028
|
+
dom.push({
|
|
8029
|
+
type: Div,
|
|
8030
|
+
className: EditorRow,
|
|
8031
|
+
translate: px(difference),
|
|
8032
|
+
childCount: textInfo.length / 2
|
|
8033
|
+
});
|
|
8034
|
+
for (let j = 0; j < textInfo.length; j += 2) {
|
|
8035
|
+
const tokenText = textInfo[j];
|
|
8036
|
+
const className = textInfo[j + 1];
|
|
8037
|
+
dom.push({
|
|
8038
|
+
type: Span,
|
|
8039
|
+
className,
|
|
8040
|
+
childCount: 1
|
|
8041
|
+
}, text(tokenText));
|
|
8042
|
+
}
|
|
8043
|
+
}
|
|
8044
|
+
return dom;
|
|
8045
|
+
};
|
|
8046
|
+
|
|
8047
|
+
const getIncrementalEdits = async (oldState, newState) => {
|
|
8048
|
+
if (!newState.undoStack) {
|
|
8049
|
+
return undefined;
|
|
8050
|
+
}
|
|
8051
|
+
const lastChanges = newState.undoStack.at(-1);
|
|
8052
|
+
if (lastChanges && lastChanges.length === 1) {
|
|
8053
|
+
const lastChange = lastChanges[0];
|
|
8054
|
+
if (lastChange.origin === EditorType) {
|
|
8055
|
+
const rowIndex = lastChange.start.rowIndex;
|
|
8056
|
+
const lines = newState.lines;
|
|
8057
|
+
const oldLine = oldState.lines[rowIndex];
|
|
8058
|
+
const newLine = lines[rowIndex];
|
|
8059
|
+
const incrementalEdits = await invoke$1('TokenizeIncremental.tokenizeIncremental', newState.uid, newState.languageId, oldLine, newLine, rowIndex, newState.minLineY);
|
|
8060
|
+
if (incrementalEdits && incrementalEdits.length === 1) {
|
|
8061
|
+
return incrementalEdits;
|
|
8062
|
+
}
|
|
8063
|
+
}
|
|
8064
|
+
}
|
|
8065
|
+
return undefined;
|
|
8066
|
+
};
|
|
8067
|
+
|
|
8068
|
+
const getSelectionsVirtualDom = selections => {
|
|
8069
|
+
const dom = [];
|
|
8070
|
+
for (let i = 0; i < selections.length; i += 4) {
|
|
8071
|
+
const x = selections[i];
|
|
8072
|
+
const y = selections[i + 1];
|
|
8073
|
+
const width = selections[i + 2];
|
|
8074
|
+
const height = selections[i + 3];
|
|
8075
|
+
dom.push({
|
|
8076
|
+
type: Div,
|
|
8077
|
+
className: EditorSelection,
|
|
8078
|
+
left: x,
|
|
8079
|
+
top: y,
|
|
8080
|
+
width,
|
|
8081
|
+
height
|
|
8082
|
+
});
|
|
8083
|
+
}
|
|
8084
|
+
return dom;
|
|
8085
|
+
};
|
|
8086
|
+
|
|
8087
|
+
const None = 'none';
|
|
8088
|
+
const Option = 'option';
|
|
8089
|
+
|
|
8090
|
+
const getFileIconVirtualDom = icon => {
|
|
8091
|
+
return {
|
|
8092
|
+
type: Img,
|
|
8093
|
+
className: FileIcon,
|
|
8094
|
+
src: icon,
|
|
8095
|
+
role: None,
|
|
8096
|
+
childCount: 0
|
|
8097
|
+
};
|
|
8098
|
+
};
|
|
8099
|
+
|
|
8100
|
+
const getIconDom = (fileIcon, symbolName) => {
|
|
8101
|
+
if (fileIcon) {
|
|
8102
|
+
return getFileIconVirtualDom(fileIcon);
|
|
8293
8103
|
}
|
|
8294
|
-
const minOffset = Math.ceil(deltaX / averageCharWidth);
|
|
8295
|
-
const maxOffset = minOffset + Math.ceil(width / averageCharWidth);
|
|
8296
8104
|
return {
|
|
8297
|
-
|
|
8298
|
-
|
|
8105
|
+
type: Div,
|
|
8106
|
+
className: `${ColoredMaskIcon} ${symbolName}`,
|
|
8107
|
+
childCount: 0
|
|
8299
8108
|
};
|
|
8300
8109
|
};
|
|
8301
|
-
|
|
8302
|
-
|
|
8303
|
-
|
|
8304
|
-
|
|
8110
|
+
|
|
8111
|
+
const label1 = {
|
|
8112
|
+
type: Div,
|
|
8113
|
+
className: Label,
|
|
8114
|
+
childCount: 1
|
|
8305
8115
|
};
|
|
8306
|
-
const
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8116
|
+
const completionHighlight = {
|
|
8117
|
+
type: Span,
|
|
8118
|
+
className: EditorCompletionItemHighlight,
|
|
8119
|
+
childCount: 1
|
|
8120
|
+
};
|
|
8121
|
+
const getHighlightedLabelDom = (label, highlights) => {
|
|
8122
|
+
if (highlights.length === 0) {
|
|
8123
|
+
return [label1, text(label)];
|
|
8314
8124
|
}
|
|
8315
|
-
const
|
|
8316
|
-
|
|
8317
|
-
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
}
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
for (let i =
|
|
8324
|
-
const
|
|
8325
|
-
const
|
|
8326
|
-
|
|
8327
|
-
|
|
8328
|
-
|
|
8329
|
-
|
|
8330
|
-
decorations[++decorationIndex];
|
|
8331
|
-
const decorationType = decorations[++decorationIndex];
|
|
8332
|
-
// @ts-ignore
|
|
8333
|
-
decorations[++decorationIndex];
|
|
8334
|
-
// console.log('MATCHING DECORATION', {
|
|
8335
|
-
// decorationIndex,
|
|
8336
|
-
// decorationLength,
|
|
8337
|
-
// decorationType,
|
|
8338
|
-
// decorationModifiers,
|
|
8339
|
-
// })
|
|
8340
|
-
extraClassName = getDecorationClassName(decorationType);
|
|
8341
|
-
}
|
|
8342
|
-
end += tokenLength;
|
|
8343
|
-
const text = line.slice(start, end);
|
|
8344
|
-
const className = `Token ${extraClassName || TokenMap[tokenType] || 'Unknown'}`;
|
|
8345
|
-
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
8346
|
-
lineInfo.push(normalizedText, className);
|
|
8347
|
-
start = end;
|
|
8348
|
-
if (end >= maxOffset) {
|
|
8349
|
-
break;
|
|
8125
|
+
const dom = [];
|
|
8126
|
+
const labelDom = {
|
|
8127
|
+
type: Div,
|
|
8128
|
+
className: Label,
|
|
8129
|
+
childCount: 0
|
|
8130
|
+
};
|
|
8131
|
+
dom.push(labelDom);
|
|
8132
|
+
let position = 0;
|
|
8133
|
+
for (let i = 0; i < highlights.length; i += 2) {
|
|
8134
|
+
const highlightStart = highlights[i];
|
|
8135
|
+
const highlightEnd = highlights[i + 1];
|
|
8136
|
+
if (position < highlightStart) {
|
|
8137
|
+
const beforeText = label.slice(position, highlightStart);
|
|
8138
|
+
labelDom.childCount++;
|
|
8139
|
+
dom.push(text(beforeText));
|
|
8350
8140
|
}
|
|
8141
|
+
const highlightText = label.slice(highlightStart, highlightEnd);
|
|
8142
|
+
labelDom.childCount++;
|
|
8143
|
+
dom.push(completionHighlight, text(highlightText));
|
|
8144
|
+
position = highlightEnd;
|
|
8351
8145
|
}
|
|
8352
|
-
|
|
8353
|
-
|
|
8354
|
-
|
|
8355
|
-
|
|
8146
|
+
if (position < label.length) {
|
|
8147
|
+
const afterText = label.slice(position);
|
|
8148
|
+
labelDom.childCount++;
|
|
8149
|
+
dom.push(text(afterText));
|
|
8150
|
+
}
|
|
8151
|
+
return dom;
|
|
8356
8152
|
};
|
|
8357
|
-
|
|
8153
|
+
|
|
8154
|
+
const getCompletionItemVirtualDom = visibleItem => {
|
|
8358
8155
|
const {
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8156
|
+
top,
|
|
8157
|
+
label,
|
|
8158
|
+
symbolName,
|
|
8159
|
+
highlights,
|
|
8160
|
+
focused,
|
|
8161
|
+
deprecated,
|
|
8162
|
+
fileIcon
|
|
8163
|
+
} = visibleItem;
|
|
8164
|
+
let className = EditorCompletionItem;
|
|
8165
|
+
if (focused) {
|
|
8166
|
+
className += ' ' + EditorCompletionItemFocused;
|
|
8367
8167
|
}
|
|
8368
|
-
|
|
8168
|
+
if (deprecated) {
|
|
8169
|
+
className += ' ' + EditorCompletionItemDeprecated;
|
|
8170
|
+
}
|
|
8171
|
+
return [{
|
|
8172
|
+
type: Div,
|
|
8173
|
+
role: Option,
|
|
8174
|
+
className,
|
|
8175
|
+
top,
|
|
8176
|
+
childCount: 2
|
|
8177
|
+
}, getIconDom(fileIcon, symbolName), ...getHighlightedLabelDom(label, highlights)];
|
|
8369
8178
|
};
|
|
8370
8179
|
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
decorations,
|
|
8378
|
-
languageId
|
|
8379
|
-
} = editor;
|
|
8380
|
-
const tokenMap = get$1(languageId);
|
|
8381
|
-
let offset = minLineOffset;
|
|
8382
|
-
const tabSize = 2;
|
|
8383
|
-
for (let i = minLineY; i < maxLineY; i++) {
|
|
8384
|
-
const line = lines[i];
|
|
8385
|
-
const normalize = shouldNormalizeText(line);
|
|
8386
|
-
const {
|
|
8387
|
-
lineInfo,
|
|
8388
|
-
difference
|
|
8389
|
-
} = getLineInfo(line, tokens[i - minLineY], embeddedResults, decorations, tokenMap, offset, normalize, tabSize, width, deltaX, averageCharWidth);
|
|
8390
|
-
result.push(lineInfo);
|
|
8391
|
-
differences.push(difference);
|
|
8392
|
-
offset += line.length + 1;
|
|
8180
|
+
const getCompletionItemsVirtualDom = visibleItems => {
|
|
8181
|
+
if (visibleItems.length === 0) {
|
|
8182
|
+
return [{
|
|
8183
|
+
type: Div,
|
|
8184
|
+
childCount: 1
|
|
8185
|
+
}, text(noResults())];
|
|
8393
8186
|
}
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
8187
|
+
const root = {
|
|
8188
|
+
type: Div,
|
|
8189
|
+
childCount: visibleItems.length
|
|
8397
8190
|
};
|
|
8191
|
+
const dom = [root, ...visibleItems.flatMap(getCompletionItemVirtualDom)];
|
|
8192
|
+
return dom;
|
|
8398
8193
|
};
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
|
|
8404
|
-
|
|
8405
|
-
|
|
8406
|
-
|
|
8407
|
-
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
8423
|
-
|
|
8424
|
-
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8194
|
+
|
|
8195
|
+
const Property = 1;
|
|
8196
|
+
const Value = 2;
|
|
8197
|
+
const Function = 3;
|
|
8198
|
+
const Variable = 4;
|
|
8199
|
+
const Keyword = 5;
|
|
8200
|
+
const Folder = 6;
|
|
8201
|
+
const File = 7;
|
|
8202
|
+
const Field = 8;
|
|
8203
|
+
|
|
8204
|
+
const SymbolProperty = 'SymbolProperty';
|
|
8205
|
+
const SymbolValue = 'SymbolValue';
|
|
8206
|
+
const SymbolFunction = 'SymbolFunction';
|
|
8207
|
+
const SymbolVariable = 'SymbolVariable';
|
|
8208
|
+
const SymbolKeyword = 'SymbolKeyword';
|
|
8209
|
+
const SymbolDefault = 'SymbolDefault';
|
|
8210
|
+
const SymbolField = 'SymbolField';
|
|
8211
|
+
const SymbolNone = '';
|
|
8212
|
+
|
|
8213
|
+
const getSymbolName = kind => {
|
|
8214
|
+
switch (kind) {
|
|
8215
|
+
case Property:
|
|
8216
|
+
return SymbolProperty;
|
|
8217
|
+
case Value:
|
|
8218
|
+
return SymbolValue;
|
|
8219
|
+
case Function:
|
|
8220
|
+
return SymbolFunction;
|
|
8221
|
+
case Variable:
|
|
8222
|
+
return SymbolVariable;
|
|
8223
|
+
case Keyword:
|
|
8224
|
+
return SymbolKeyword;
|
|
8225
|
+
case Field:
|
|
8226
|
+
return SymbolField;
|
|
8227
|
+
case File:
|
|
8228
|
+
return SymbolNone;
|
|
8229
|
+
default:
|
|
8230
|
+
return SymbolDefault;
|
|
8231
|
+
}
|
|
8232
|
+
};
|
|
8233
|
+
|
|
8234
|
+
// TODO
|
|
8235
|
+
const getCompletionFileIcon = kind => {
|
|
8236
|
+
switch (kind) {
|
|
8237
|
+
case File:
|
|
8238
|
+
return EmptyString;
|
|
8239
|
+
case Folder:
|
|
8240
|
+
return EmptyString;
|
|
8241
|
+
default:
|
|
8242
|
+
return EmptyString;
|
|
8432
8243
|
}
|
|
8244
|
+
};
|
|
8245
|
+
|
|
8246
|
+
const getHighlights = item => {
|
|
8247
|
+
const {
|
|
8248
|
+
matches
|
|
8249
|
+
} = item;
|
|
8250
|
+
return matches.slice(1);
|
|
8251
|
+
};
|
|
8252
|
+
|
|
8253
|
+
const getLabel = item => {
|
|
8254
|
+
return item.label;
|
|
8255
|
+
};
|
|
8256
|
+
const getVisibleIem = (item, itemHeight, leadingWord, i, focusedIndex) => {
|
|
8433
8257
|
return {
|
|
8434
|
-
|
|
8435
|
-
|
|
8258
|
+
label: getLabel(item),
|
|
8259
|
+
symbolName: getSymbolName(item.kind),
|
|
8260
|
+
top: i * itemHeight,
|
|
8261
|
+
highlights: getHighlights(item),
|
|
8262
|
+
focused: i === focusedIndex,
|
|
8263
|
+
deprecated: item.flags & Deprecated,
|
|
8264
|
+
fileIcon: getCompletionFileIcon(item.kind)
|
|
8436
8265
|
};
|
|
8437
8266
|
};
|
|
8438
8267
|
|
|
8439
|
-
const
|
|
8440
|
-
const
|
|
8441
|
-
for (
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
className: EditorCursor,
|
|
8445
|
-
translate
|
|
8446
|
-
});
|
|
8268
|
+
const getVisibleItems = (filteredItems, itemHeight, leadingWord, minLineY, maxLineY, focusedIndex) => {
|
|
8269
|
+
const visibleItems = [];
|
|
8270
|
+
for (let i = minLineY; i < maxLineY; i++) {
|
|
8271
|
+
const filteredItem = filteredItems[i];
|
|
8272
|
+
visibleItems.push(getVisibleIem(filteredItem, itemHeight, leadingWord, i, focusedIndex));
|
|
8447
8273
|
}
|
|
8448
|
-
return
|
|
8274
|
+
return visibleItems;
|
|
8449
8275
|
};
|
|
8450
8276
|
|
|
8451
|
-
const
|
|
8452
|
-
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
case Warning:
|
|
8460
|
-
return 'DiagnosticWarning';
|
|
8461
|
-
default:
|
|
8462
|
-
return 'DiagnosticError';
|
|
8277
|
+
const renderItems = {
|
|
8278
|
+
isEqual(oldState, newState) {
|
|
8279
|
+
return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.focusedIndex === newState.focusedIndex;
|
|
8280
|
+
},
|
|
8281
|
+
apply(oldState, newState) {
|
|
8282
|
+
const visibleItems = getVisibleItems(newState.items, newState.itemHeight, newState.leadingWord, newState.minLineY, newState.maxLineY, newState.focusedIndex);
|
|
8283
|
+
const dom = getCompletionItemsVirtualDom(visibleItems);
|
|
8284
|
+
return ['setDom', dom];
|
|
8463
8285
|
}
|
|
8464
8286
|
};
|
|
8465
|
-
const
|
|
8466
|
-
|
|
8467
|
-
x
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
height,
|
|
8479
|
-
top: y,
|
|
8480
|
-
left: x,
|
|
8481
|
-
childCount: 0
|
|
8482
|
-
}];
|
|
8287
|
+
const renderBounds = {
|
|
8288
|
+
isEqual(oldState, newState) {
|
|
8289
|
+
return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.x === newState.x && oldState.y === newState.y;
|
|
8290
|
+
},
|
|
8291
|
+
apply(oldState, newState) {
|
|
8292
|
+
const {
|
|
8293
|
+
x,
|
|
8294
|
+
y,
|
|
8295
|
+
width,
|
|
8296
|
+
height
|
|
8297
|
+
} = newState;
|
|
8298
|
+
return [/* method */SetBounds, /* x */x, /* y */y, /* width */width, /* height */height];
|
|
8299
|
+
}
|
|
8483
8300
|
};
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8301
|
+
const renderHeight = {
|
|
8302
|
+
isEqual(oldState, newState) {
|
|
8303
|
+
return oldState.items.length === newState.items.length;
|
|
8304
|
+
},
|
|
8305
|
+
apply(oldState, newState) {
|
|
8306
|
+
const {
|
|
8307
|
+
itemHeight
|
|
8308
|
+
} = newState;
|
|
8309
|
+
const contentHeight = newState.items.length * itemHeight;
|
|
8310
|
+
return [/* method */SetContentHeight, /* contentHeight */contentHeight];
|
|
8311
|
+
}
|
|
8488
8312
|
};
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
}
|
|
8313
|
+
const renderNegativeMargin = {
|
|
8314
|
+
isEqual(oldState, newState) {
|
|
8315
|
+
return oldState.deltaY === newState.deltaY;
|
|
8316
|
+
},
|
|
8317
|
+
apply(oldState, newState) {
|
|
8318
|
+
return [/* method */SetNegativeMargin, /* negativeMargin */-newState.deltaY];
|
|
8319
|
+
}
|
|
8496
8320
|
};
|
|
8497
|
-
const
|
|
8498
|
-
|
|
8499
|
-
|
|
8321
|
+
const renderScrollBar = {
|
|
8322
|
+
isEqual(oldState, newState) {
|
|
8323
|
+
return oldState.negativeMargin === newState.negativeMargin && oldState.deltaY === newState.deltaY && oldState.height === newState.height && oldState.finalDeltaY === newState.finalDeltaY && oldState.items.length === newState.items.length;
|
|
8324
|
+
},
|
|
8325
|
+
apply(oldState, newState) {
|
|
8326
|
+
const total = newState.items.length;
|
|
8327
|
+
const contentHeight = total * newState.itemHeight;
|
|
8328
|
+
const scrollBarHeight = getScrollBarSize(newState.height, contentHeight, newState.minimumSliderSize);
|
|
8329
|
+
const scrollBarY = getScrollBarY(newState.deltaY, newState.finalDeltaY, newState.height - newState.headerHeight, scrollBarHeight);
|
|
8330
|
+
return [/* method */SetScrollBar, /* scrollBarY */scrollBarY, /* scrollBarHeight */scrollBarHeight];
|
|
8331
|
+
}
|
|
8500
8332
|
};
|
|
8501
|
-
|
|
8502
|
-
const
|
|
8503
|
-
const
|
|
8504
|
-
for (
|
|
8505
|
-
|
|
8506
|
-
|
|
8507
|
-
dom.push({
|
|
8508
|
-
type: Div,
|
|
8509
|
-
className: EditorRow,
|
|
8510
|
-
translate: px(difference),
|
|
8511
|
-
childCount: textInfo.length / 2
|
|
8512
|
-
});
|
|
8513
|
-
for (let j = 0; j < textInfo.length; j += 2) {
|
|
8514
|
-
const tokenText = textInfo[j];
|
|
8515
|
-
const className = textInfo[j + 1];
|
|
8516
|
-
dom.push({
|
|
8517
|
-
type: Span,
|
|
8518
|
-
className,
|
|
8519
|
-
childCount: 1
|
|
8520
|
-
}, text(tokenText));
|
|
8333
|
+
const render$2 = [renderItems, renderBounds, renderHeight, renderNegativeMargin, renderScrollBar];
|
|
8334
|
+
const renderCompletion = (oldState, newState) => {
|
|
8335
|
+
const commands = [];
|
|
8336
|
+
for (const item of render$2) {
|
|
8337
|
+
if (!item.isEqual(oldState, newState)) {
|
|
8338
|
+
commands.push(item.apply(oldState, newState));
|
|
8521
8339
|
}
|
|
8522
8340
|
}
|
|
8523
|
-
return
|
|
8341
|
+
return commands;
|
|
8524
8342
|
};
|
|
8525
8343
|
|
|
8526
|
-
const
|
|
8527
|
-
|
|
8528
|
-
|
|
8344
|
+
const render$1 = (oldState, newState) => {
|
|
8345
|
+
const commands = renderCompletion(oldState, newState);
|
|
8346
|
+
const wrappedCommands = [];
|
|
8347
|
+
const uid = newState.uid;
|
|
8348
|
+
for (const command of commands) {
|
|
8349
|
+
wrappedCommands.push(['Viewlet.send', uid, ...command]);
|
|
8529
8350
|
}
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8351
|
+
return wrappedCommands;
|
|
8352
|
+
};
|
|
8353
|
+
const add = widget => {
|
|
8354
|
+
const commands = render$1(widget.oldState, widget.newState);
|
|
8355
|
+
const id = 'EditorCompletion';
|
|
8356
|
+
// TODO how to generate a unique integer id
|
|
8357
|
+
// that doesn't collide with ids created in renderer worker?
|
|
8358
|
+
const uid = widget.newState.uid;
|
|
8359
|
+
const allCommands = [];
|
|
8360
|
+
allCommands.push(['Viewlet.create', id, uid]);
|
|
8361
|
+
allCommands.push(...commands);
|
|
8362
|
+
return allCommands;
|
|
8363
|
+
};
|
|
8364
|
+
const remove = widget => {
|
|
8365
|
+
return [['Viewlet.send', widget.newState.uid, 'dispose']];
|
|
8366
|
+
};
|
|
8367
|
+
const handleEditorType = (editor, state) => {
|
|
8368
|
+
const {
|
|
8369
|
+
unfilteredItems,
|
|
8370
|
+
itemHeight,
|
|
8371
|
+
maxHeight
|
|
8372
|
+
} = state;
|
|
8373
|
+
const {
|
|
8374
|
+
selections
|
|
8375
|
+
} = editor;
|
|
8376
|
+
const rowIndex = selections[0];
|
|
8377
|
+
const columnIndex = selections[1];
|
|
8378
|
+
const x$1 = x(editor, rowIndex, columnIndex);
|
|
8379
|
+
const y$1 = y(editor, rowIndex);
|
|
8380
|
+
const wordAtOffset = getWordBefore(editor, rowIndex, columnIndex);
|
|
8381
|
+
const items = filterCompletionItems(unfilteredItems, wordAtOffset);
|
|
8382
|
+
const newMinLineY = 0;
|
|
8383
|
+
const newMaxLineY = Math.min(items.length, 8);
|
|
8384
|
+
const height = getListHeight(items.length, itemHeight, maxHeight);
|
|
8385
|
+
const finalDeltaY = items.length * itemHeight - height;
|
|
8386
|
+
return {
|
|
8387
|
+
...state,
|
|
8388
|
+
items,
|
|
8389
|
+
x: x$1,
|
|
8390
|
+
y: y$1,
|
|
8391
|
+
minLineY: newMinLineY,
|
|
8392
|
+
maxLineY: newMaxLineY,
|
|
8393
|
+
leadingWord: wordAtOffset,
|
|
8394
|
+
height,
|
|
8395
|
+
finalDeltaY
|
|
8396
|
+
};
|
|
8397
|
+
};
|
|
8398
|
+
const handleEditorDeleteLeft = (editor, state) => {
|
|
8399
|
+
const {
|
|
8400
|
+
unfilteredItems,
|
|
8401
|
+
itemHeight,
|
|
8402
|
+
maxHeight
|
|
8403
|
+
} = state;
|
|
8404
|
+
const {
|
|
8405
|
+
selections
|
|
8406
|
+
} = editor;
|
|
8407
|
+
const rowIndex = selections[0];
|
|
8408
|
+
const columnIndex = selections[1];
|
|
8409
|
+
const x$1 = x(editor, rowIndex, columnIndex);
|
|
8410
|
+
const y$1 = y(editor, rowIndex);
|
|
8411
|
+
const wordAtOffset = getWordBefore(editor, rowIndex, columnIndex);
|
|
8412
|
+
if (!wordAtOffset) {
|
|
8413
|
+
return undefined;
|
|
8543
8414
|
}
|
|
8544
|
-
|
|
8415
|
+
const items = filterCompletionItems(unfilteredItems, wordAtOffset);
|
|
8416
|
+
const newMaxLineY = Math.min(items.length, 8);
|
|
8417
|
+
const height = getListHeight(items.length, itemHeight, maxHeight);
|
|
8418
|
+
return {
|
|
8419
|
+
...state,
|
|
8420
|
+
items,
|
|
8421
|
+
x: x$1,
|
|
8422
|
+
y: y$1,
|
|
8423
|
+
maxLineY: newMaxLineY,
|
|
8424
|
+
leadingWord: wordAtOffset,
|
|
8425
|
+
height
|
|
8426
|
+
};
|
|
8545
8427
|
};
|
|
8546
8428
|
|
|
8547
|
-
const
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
dom.push({
|
|
8555
|
-
type: Div,
|
|
8556
|
-
className: EditorSelection,
|
|
8557
|
-
left: x,
|
|
8558
|
-
top: y,
|
|
8559
|
-
width,
|
|
8560
|
-
height
|
|
8561
|
-
});
|
|
8562
|
-
}
|
|
8563
|
-
return dom;
|
|
8429
|
+
const EditorCompletionWidget = {
|
|
8430
|
+
__proto__: null,
|
|
8431
|
+
add,
|
|
8432
|
+
handleEditorDeleteLeft,
|
|
8433
|
+
handleEditorType,
|
|
8434
|
+
remove,
|
|
8435
|
+
render: render$1
|
|
8564
8436
|
};
|
|
8565
8437
|
|
|
8566
8438
|
const addWidget = widget => {
|
|
@@ -8580,7 +8452,7 @@ const renderWidget = widget => {
|
|
|
8580
8452
|
} = widget;
|
|
8581
8453
|
switch (id) {
|
|
8582
8454
|
case Completion:
|
|
8583
|
-
return render$
|
|
8455
|
+
return render$1(widget.oldState, widget.newState);
|
|
8584
8456
|
default:
|
|
8585
8457
|
throw new Error(`unsupported widget`);
|
|
8586
8458
|
}
|
|
@@ -8591,7 +8463,7 @@ const removeWidget = widget => {
|
|
|
8591
8463
|
} = widget;
|
|
8592
8464
|
switch (id) {
|
|
8593
8465
|
case Completion:
|
|
8594
|
-
return remove
|
|
8466
|
+
return remove(widget);
|
|
8595
8467
|
default:
|
|
8596
8468
|
throw new Error('unsupported widget');
|
|
8597
8469
|
}
|
|
@@ -8939,8 +8811,8 @@ const commandMap = {
|
|
|
8939
8811
|
'EditorCompletion.focusPrevious': focusPrevious$1,
|
|
8940
8812
|
'EditorCompletion.handleEditorBlur': handleEditorBlur,
|
|
8941
8813
|
'EditorCompletion.handleEditorClick': handleEditorClick,
|
|
8942
|
-
'EditorCompletion.handleEditorDeleteLeft': handleEditorDeleteLeft,
|
|
8943
|
-
'EditorCompletion.handleEditorType': handleEditorType,
|
|
8814
|
+
'EditorCompletion.handleEditorDeleteLeft': handleEditorDeleteLeft$1,
|
|
8815
|
+
'EditorCompletion.handleEditorType': handleEditorType$1,
|
|
8944
8816
|
'EditorCompletion.loadContent': loadContent$2,
|
|
8945
8817
|
'EditorCompletion.selectCurrent': selectCurrent,
|
|
8946
8818
|
'EditorCompletion.selectIndex': selectIndex,
|
|
@@ -9381,6 +9253,7 @@ const listen$1 = async ({
|
|
|
9381
9253
|
|
|
9382
9254
|
const listen = async () => {
|
|
9383
9255
|
registerCommands(commandMap);
|
|
9256
|
+
register(Completion, EditorCompletionWidget);
|
|
9384
9257
|
const ipc = await listen$1({
|
|
9385
9258
|
method: Auto()
|
|
9386
9259
|
});
|