@lvce-editor/editor-worker 2.0.0 → 2.1.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.
Files changed (2) hide show
  1. package/dist/editorWorkerMain.js +1231 -1160
  2. package/package.json +1 -1
@@ -109,6 +109,120 @@ const handleSliderPointerMove = (state, x, y) => {
109
109
  };
110
110
  };
111
111
 
112
+ const ColoredMaskIcon = 'ColoredMaskIcon';
113
+ const ColorPicker = 'ColorPicker';
114
+ const ColorPickerBackgroundColor = 'ColorPickerBackgroundColor';
115
+ const ColorPickerDark = 'ColorPickerDark';
116
+ const ColorPickerLight = 'ColorPickerLight';
117
+ const ColorPickerRectangle = 'ColorPickerRectangle';
118
+ const ColorPickerSlider = 'ColorPickerSlider';
119
+ const ColorPickerSliderThumb = 'ColorPickerSliderThumb';
120
+ const Diagnostic = 'Diagnostic';
121
+ const EditorCompletionItem = 'EditorCompletionItem';
122
+ const EditorCompletionItemDeprecated = 'EditorCompletionItemDeprecated';
123
+ const EditorCompletionItemFocused = 'EditorCompletionItemFocused';
124
+ const EditorCompletionItemHighlight = 'EditorCompletionItemHighlight';
125
+ const EditorCursor = 'EditorCursor';
126
+ const EditorRow = 'EditorRow';
127
+ const EditorSelection = 'EditorSelection';
128
+ const FileIcon = 'FileIcon';
129
+ const HoverDisplayString = 'HoverDisplayString';
130
+ const HoverDocumentation = 'HoverDocumentation';
131
+ const HoverEditorRow = 'HoverEditorRow';
132
+ const HoverProblem = 'HoverProblem';
133
+ const HoverProblemDetail = 'HoverProblemDetail';
134
+ const HoverProblemMessage = 'HoverProblemMessage';
135
+ const Label = 'Label';
136
+ const Viewlet = 'Viewlet';
137
+
138
+ const HandlePointerDown = 'handlePointerDown';
139
+ const HandleSashPointerDown = 'handleSashPointerDown';
140
+
141
+ const mergeClassNames = (...classNames) => {
142
+ return classNames.filter(Boolean).join(' ');
143
+ };
144
+
145
+ const Div = 4;
146
+ const Span = 8;
147
+ const Text = 12;
148
+ const Img = 17;
149
+
150
+ const getColorPickerVirtualDom = () => {
151
+ return [{
152
+ type: Div,
153
+ className: mergeClassNames(Viewlet, ColorPicker),
154
+ onPointerDown: HandlePointerDown,
155
+ childCount: 3
156
+ }, {
157
+ type: Div,
158
+ className: ColorPickerRectangle,
159
+ childCount: 3
160
+ }, {
161
+ type: Div,
162
+ className: ColorPickerBackgroundColor,
163
+ childCount: 0
164
+ }, {
165
+ type: Div,
166
+ className: ColorPickerLight,
167
+ childCount: 0
168
+ }, {
169
+ type: Div,
170
+ className: ColorPickerDark,
171
+ childCount: 0
172
+ }, {
173
+ type: Div,
174
+ className: ColorPickerSlider,
175
+ childCount: 0
176
+ }, {
177
+ type: Div,
178
+ className: ColorPickerSliderThumb,
179
+ childCount: 0
180
+ }];
181
+ };
182
+
183
+ const SetBounds = 'setBounds';
184
+ const SetColor = 'setColor';
185
+ const SetContentHeight = 'setContentHeight';
186
+ const SetNegativeMargin = 'setNegativeMargin';
187
+ const SetOffsetX = 'setOffsetX';
188
+ const SetScrollBar = 'setScrollBar';
189
+
190
+ const renderColor = {
191
+ isEqual(oldState, newState) {
192
+ return oldState.color === newState.color;
193
+ },
194
+ apply(oldState, newState) {
195
+ return [/* method */SetColor, /* color */newState.color];
196
+ }
197
+ };
198
+ const renderOffsetX = {
199
+ isEqual(oldState, newState) {
200
+ return oldState.offsetX === newState.offsetX;
201
+ },
202
+ apply(oldState, newState) {
203
+ return [/* method */SetOffsetX, /* offsetX */newState.offsetX];
204
+ }
205
+ };
206
+ const renderColorPickerDom = {
207
+ isEqual(oldState, newState) {
208
+ return oldState.min === newState.min && oldState.max === newState.max;
209
+ },
210
+ apply(oldState, newState) {
211
+ const dom = getColorPickerVirtualDom();
212
+ return ['Viewlet.setDom2', dom];
213
+ }
214
+ };
215
+ const render$3 = [renderColorPickerDom, renderColor, renderOffsetX];
216
+ const renderColorPicker = async (oldState, newState) => {
217
+ const commands = [];
218
+ for (const item of render$3) {
219
+ if (!item.isEqual(oldState, newState)) {
220
+ commands.push(item.apply(oldState, newState));
221
+ }
222
+ }
223
+ return commands;
224
+ };
225
+
112
226
  // TODO use numeric enum
113
227
  const CompositionUpdate = 'compositionUpdate';
114
228
  const ContentEditableInput = 'contentEditableInput';
@@ -4463,180 +4577,653 @@ const moveSelectionPx = (editor, x, y) => {
4463
4577
  return editorMoveSelection(editor, position);
4464
4578
  };
4465
4579
 
4466
- const FindWidget = 'FindWidget';
4467
- const openFind = async state => {
4468
- await invoke$3('Viewlet.openWidget', FindWidget);
4469
- return state;
4580
+ const OnCompletion = 'onCompletion';
4581
+ const OnHover = 'onHover';
4582
+
4583
+ // TODO add tests for this
4584
+ const activateByEvent = async event => {
4585
+ await invoke$3('ExtensionHostManagement.activateByEvent', event);
4470
4586
  };
4471
4587
 
4472
- const getEditor = editorUid => {
4473
- const instance = get$6(editorUid);
4474
- if (!instance) {
4475
- throw new Error(`editor ${editorUid} not found`);
4476
- }
4477
- const {
4478
- newState
4479
- } = instance;
4480
- return newState;
4588
+ const execute = async ({
4589
+ editor,
4590
+ args,
4591
+ event,
4592
+ method,
4593
+ noProviderFoundMessage,
4594
+ noProviderFoundResult = undefined
4595
+ }) => {
4596
+ const fullEvent = `${event}:${editor.languageId}`;
4597
+ await activateByEvent(fullEvent);
4598
+ const result = await invoke$2(method, editor.uid, ...args);
4599
+ return result;
4481
4600
  };
4482
4601
 
4483
- const getText = editorUid => {
4484
- const editor = getEditor(editorUid);
4602
+ const combineResults = results => {
4603
+ return results[0] ?? [];
4604
+ };
4605
+ const executeCompletionProvider = (editor, offset) => {
4606
+ return execute({
4607
+ editor,
4608
+ event: OnCompletion,
4609
+ method: CompletionExecute,
4610
+ args: [offset],
4611
+ noProviderFoundMessage: 'no completion provider found',
4612
+ noProviderFoundResult: [],
4613
+ combineResults
4614
+ });
4615
+ };
4616
+ const combineResultsResolve = items => {
4617
+ return items[0] ?? undefined;
4618
+ };
4619
+ const executeResolveCompletionItem = (editor, offset, name, completionItem) => {
4620
+ return execute({
4621
+ editor,
4622
+ event: OnCompletion,
4623
+ method: CompletionResolveExecute,
4624
+ args: [offset, name, completionItem],
4625
+ noProviderFoundMessage: 'no completion provider found',
4626
+ noProviderFoundResult: [],
4627
+ combineResults: combineResultsResolve
4628
+ });
4629
+ };
4630
+
4631
+ // TODO possible to do this with events/state machine instead of promises -> enables canceling operations / concurrent calls
4632
+ const getCompletions = async editor => {
4485
4633
  const {
4486
- lines
4634
+ selections
4487
4635
  } = editor;
4488
- return lines.join('\n');
4636
+ const rowIndex = selections[0];
4637
+ const columnIndex = selections[1];
4638
+ // Editor.sync(editor)
4639
+ const offset = await offsetAt(editor, rowIndex, columnIndex);
4640
+ const completions = await executeCompletionProvider(editor, offset);
4641
+ return completions;
4489
4642
  };
4490
4643
 
4491
- const organizeImports = async editor => {
4492
- // TODO ask extension host worker directly
4493
- const edits = await invoke$3('ExtensionHostOrganizeImports.organizeImports', editor);
4494
- console.log({
4495
- edits
4496
- });
4497
- return applyDocumentEdits(editor, edits);
4644
+ // TODO don't send unnecessary parts of completion item like matches
4645
+ const resolveCompletion = async (editor, name, completionItem) => {
4646
+ try {
4647
+ object(editor);
4648
+ string(name);
4649
+ object(completionItem);
4650
+ const rowIndex = editor.selections[0];
4651
+ const columnIndex = editor.selections[1];
4652
+ const offset = await offsetAt(editor, rowIndex, columnIndex);
4653
+ // @ts-ignore
4654
+ const resolvedCompletionItem = await executeResolveCompletionItem(editor, offset, name, completionItem);
4655
+ return resolvedCompletionItem;
4656
+ } catch {
4657
+ return undefined;
4658
+ }
4498
4659
  };
4499
4660
 
4500
- // @ts-ignore
4661
+ const None$1 = 1;
4501
4662
 
4502
- // @ts-ignore
4503
- const pasteText = (editor, text) => {
4504
- const insertedLines = splitLines$2(text);
4505
- const changes = editorReplaceSelections(editor, insertedLines, EditorPasteText);
4506
- return scheduleDocumentAndCursorsSelections(editor, changes);
4663
+ const EmptyMatches = [];
4664
+
4665
+ const Diagonal = 1;
4666
+ const Left = 2;
4667
+
4668
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
4669
+
4670
+ const createTable = size => {
4671
+ const table = [];
4672
+ for (let i = 0; i < size; i++) {
4673
+ const row = new Uint8Array(size);
4674
+ table.push(row);
4675
+ }
4676
+ return table;
4507
4677
  };
4508
4678
 
4509
- const paste = async editor => {
4510
- const text = await invoke$3('ClipBoard.readText');
4511
- string(text);
4512
- return pasteText(editor, text);
4679
+ const isLowerCase = char => {
4680
+ return char === char.toLowerCase();
4513
4681
  };
4514
4682
 
4515
- const getErrorMessage$1 = error => {
4516
- if (!error) {
4517
- return `Error: ${error}`;
4518
- }
4519
- let message = error.message;
4520
- while (error.cause) {
4521
- error = error.cause;
4522
- message += `: ${error}`;
4523
- }
4524
- return message;
4683
+ const isUpperCase = char => {
4684
+ return char === char.toUpperCase();
4525
4685
  };
4526
- const prepareErrorMessageWithCodeFrame = error => {
4527
- if (!error) {
4528
- return {
4529
- message: error,
4530
- stack: undefined,
4531
- codeFrame: undefined,
4532
- type: 'Error'
4533
- };
4534
- }
4535
- const message = getErrorMessage$1(error);
4536
- if (error.codeFrame) {
4537
- return {
4538
- message,
4539
- stack: error.stack,
4540
- codeFrame: error.codeFrame,
4541
- type: error.constructor.name
4542
- };
4686
+
4687
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
4688
+ const isGap = (columnCharBefore, columnChar) => {
4689
+ switch (columnCharBefore) {
4690
+ case Dash:
4691
+ case Underline:
4692
+ case EmptyString:
4693
+ case T:
4694
+ case Space:
4695
+ case Dot:
4696
+ return true;
4543
4697
  }
4544
- return {
4545
- message,
4546
- stack: error.originalStack,
4547
- codeFrame: error.originalCodeFrame,
4548
- category: error.category,
4549
- stderr: error.stderr
4550
- };
4698
+ if (isLowerCase(columnCharBefore) && isUpperCase(columnChar)) {
4699
+ return true;
4700
+ }
4701
+ return false;
4551
4702
  };
4552
- const RE_PATH_1 = /\((.*):(\d+):(\d+)\)$/;
4553
- const RE_PATH_2 = /at (.*):(\d+):(\d+)$/;
4554
4703
 
4555
- /**
4556
- *
4557
- * @param {readonly string[]} lines
4558
- * @returns
4559
- */
4560
- const getFile = lines => {
4561
- for (const line of lines) {
4562
- if (RE_PATH_1.test(line) || RE_PATH_2.test(line)) {
4563
- return line;
4564
- }
4704
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
4705
+ const getScore = (rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, column, wordLength, isDiagonalMatch) => {
4706
+ if (rowCharLow !== columnCharLow) {
4707
+ return -1;
4565
4708
  }
4566
- return '';
4567
- };
4568
- const prepareErrorMessageWithoutCodeFrame = async error => {
4569
- try {
4570
- const lines = splitLines$2(error.stack);
4571
- const file = getFile(lines);
4572
- let match = file.match(RE_PATH_1);
4573
- if (!match) {
4574
- match = file.match(RE_PATH_2);
4709
+ const isMatch = rowChar === columnChar;
4710
+ if (isMatch) {
4711
+ if (isDiagonalMatch) {
4712
+ return 8;
4575
4713
  }
4576
- if (!match) {
4577
- return error;
4714
+ if (isGap(columnCharBefore, columnChar)) {
4715
+ return 8;
4578
4716
  }
4579
- const relevantStack = joinLines$2(lines.slice(1));
4580
- const message = getErrorMessage$1(error);
4581
- return {
4582
- message,
4583
- stack: relevantStack,
4584
- type: error.constructor.name
4585
- };
4586
- } catch (otherError) {
4587
- console.warn('ErrorHandling Error');
4588
- console.warn(otherError);
4589
- return error;
4717
+ return 5;
4718
+ }
4719
+ if (isGap(columnCharBefore, columnChar)) {
4720
+ return 8;
4590
4721
  }
4722
+ return 5;
4591
4723
  };
4592
- const prepare = async error => {
4593
- if (error && error.message && error.codeFrame) {
4594
- return prepareErrorMessageWithCodeFrame(error);
4724
+
4725
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
4726
+
4727
+ const isPatternInWord = (patternLow, patternPos, patternLen, wordLow, wordPos, wordLen) => {
4728
+ while (patternPos < patternLen && wordPos < wordLen) {
4729
+ if (patternLow[patternPos] === wordLow[wordPos]) {
4730
+ patternPos += 1;
4731
+ }
4732
+ wordPos += 1;
4595
4733
  }
4596
- if (error && error.stack) {
4597
- return prepareErrorMessageWithoutCodeFrame(error);
4734
+ return patternPos === patternLen; // pattern must be exhausted
4735
+ };
4736
+
4737
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
4738
+ const traceHighlights = (table, arrows, patternLength, wordLength) => {
4739
+ let row = patternLength;
4740
+ let column = wordLength;
4741
+ const matches = [];
4742
+ while (row >= 1 && column >= 1) {
4743
+ const arrow = arrows[row][column];
4744
+ if (arrow === Left) {
4745
+ column--;
4746
+ } else if (arrow === Diagonal) {
4747
+ row--;
4748
+ column--;
4749
+ const start = column + 1;
4750
+ while (row >= 1 && column >= 1) {
4751
+ const arrow = arrows[row][column];
4752
+ if (arrow === Left) {
4753
+ break;
4754
+ }
4755
+ if (arrow === Diagonal) {
4756
+ row--;
4757
+ column--;
4758
+ }
4759
+ }
4760
+ const end = column;
4761
+ matches.unshift(end, start);
4762
+ }
4598
4763
  }
4599
- return error;
4764
+ matches.unshift(table[patternLength][wordLength - 1]);
4765
+ return matches;
4600
4766
  };
4601
- const print = error => {
4602
- if (error && error.type && error.message && error.codeFrame) {
4603
- return `${error.type}: ${error.message}\n\n${error.codeFrame}\n\n${error.stack}`;
4767
+
4768
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
4769
+ const gridSize = 128;
4770
+ const table = createTable(gridSize);
4771
+ const arrows = createTable(gridSize);
4772
+ // @ts-ignore
4773
+ createTable(gridSize);
4774
+ const filterCompletionItem = (pattern, word) => {
4775
+ const patternLength = Math.min(pattern.length, gridSize - 1);
4776
+ const wordLength = Math.min(word.length, gridSize - 1);
4777
+ const patternLower = pattern.toLowerCase();
4778
+ const wordLower = word.toLowerCase();
4779
+ if (!isPatternInWord(patternLower, 0, patternLength, wordLower, 0, wordLength)) {
4780
+ return EmptyMatches;
4604
4781
  }
4605
- if (error && error.message && error.codeFrame) {
4606
- return `${error.message}\n\n${error.codeFrame}\n\n${error.stack}`;
4782
+ let strongMatch = false;
4783
+ for (let row = 1; row < patternLength + 1; row++) {
4784
+ const rowChar = pattern[row - 1];
4785
+ const rowCharLow = patternLower[row - 1];
4786
+ for (let column = 1; column < wordLength + 1; column++) {
4787
+ const columnChar = word[column - 1];
4788
+ const columnCharLow = wordLower[column - 1];
4789
+ const columnCharBefore = word[column - 2] || '';
4790
+ const isDiagonalMatch = arrows[row - 1][column - 1] === Diagonal;
4791
+ const score = getScore(rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, column, wordLength, isDiagonalMatch);
4792
+ if (row === 1 && score > 5) {
4793
+ strongMatch = true;
4794
+ }
4795
+ let diagonalScore = score + table[row - 1][column - 1];
4796
+ if (isDiagonalMatch && score !== -1) {
4797
+ diagonalScore += 2;
4798
+ }
4799
+ const leftScore = table[row][column - 1];
4800
+ if (leftScore > diagonalScore) {
4801
+ table[row][column] = leftScore;
4802
+ arrows[row][column] = Left;
4803
+ } else {
4804
+ table[row][column] = diagonalScore;
4805
+ arrows[row][column] = Diagonal;
4806
+ }
4807
+ }
4607
4808
  }
4608
- if (error && error.type && error.message) {
4609
- return `${error.type}: ${error.message}\n${error.stack}`;
4809
+ if (!strongMatch) {
4810
+ return EmptyMatches;
4610
4811
  }
4611
- if (error && error.stack) {
4612
- return `${error.stack}`;
4812
+ // printTables(pattern, 0, word, 0)
4813
+ const highlights = traceHighlights(table, arrows, patternLength, wordLength);
4814
+ return highlights;
4815
+ };
4816
+
4817
+ const Deprecated = 1 << 0;
4818
+
4819
+ const addEmptyMatch = item => {
4820
+ return {
4821
+ ...item,
4822
+ matches: EmptyMatches
4823
+ };
4824
+ };
4825
+ const filterCompletionItems = (completionItems, word) => {
4826
+ if (word === EmptyString) {
4827
+ return completionItems.map(addEmptyMatch);
4613
4828
  }
4614
- if (error === null) {
4615
- return null;
4829
+ const filteredCompletions = [];
4830
+ const deprecated = [];
4831
+ for (const completionItem of completionItems) {
4832
+ const {
4833
+ label,
4834
+ flags
4835
+ } = completionItem;
4836
+ const result = filterCompletionItem(word, label);
4837
+ if (result !== EmptyMatches) {
4838
+ if (flags & Deprecated) {
4839
+ // TODO avoid mutation
4840
+ completionItem.matches = EmptyMatches;
4841
+ deprecated.push(completionItem);
4842
+ } else {
4843
+ // TODO avoid mutation
4844
+ completionItem.matches = result;
4845
+ filteredCompletions.push(completionItem);
4846
+ }
4847
+ }
4616
4848
  }
4617
- return `${error}`;
4849
+ if (deprecated.length > 0) {
4850
+ filteredCompletions.push(...deprecated);
4851
+ }
4852
+ return filteredCompletions;
4618
4853
  };
4619
4854
 
4620
- // @ts-nocheck
4621
- const logError = async error => {
4622
- const prettyError = await prepare(error);
4623
- const prettyErrorString = print(prettyError);
4624
- console.error(prettyErrorString);
4625
- return prettyError;
4855
+ const getFinalDeltaY = (height, itemHeight, itemsLength) => {
4856
+ const contentHeight = itemsLength * itemHeight;
4857
+ const finalDeltaY = Math.max(contentHeight - height, 0);
4858
+ return finalDeltaY;
4626
4859
  };
4627
- const handleError = async error => {
4628
- try {
4629
- const prettyError = await logError(error);
4630
- } catch (otherError) {
4631
- console.warn('ErrorHandling error');
4632
- console.warn(otherError);
4633
- console.error(error);
4860
+
4861
+ const getListHeight = (itemsLength, itemHeight, maxHeight) => {
4862
+ number$1(itemsLength);
4863
+ number$1(itemHeight);
4864
+ number$1(maxHeight);
4865
+ if (itemsLength === 0) {
4866
+ return itemHeight;
4634
4867
  }
4868
+ const totalHeight = itemsLength * itemHeight;
4869
+ return Math.min(totalHeight, maxHeight);
4635
4870
  };
4636
4871
 
4637
- // @ts-ignore
4638
- const getNewEditor = async editor => {
4639
- return editor;
4872
+ const getEditor = editorUid => {
4873
+ const instance = get$6(editorUid);
4874
+ if (!instance) {
4875
+ throw new Error(`editor ${editorUid} not found`);
4876
+ }
4877
+ const {
4878
+ newState
4879
+ } = instance;
4880
+ return newState;
4881
+ };
4882
+
4883
+ const RE_WORD = /[\w\-]+$/;
4884
+ const getWordAtOffset = editor => {
4885
+ const {
4886
+ lines,
4887
+ selections
4888
+ } = editor;
4889
+ const rowIndex = selections[0];
4890
+ const columnIndex = selections[1];
4891
+ const line = lines[rowIndex];
4892
+ const part = line.slice(0, columnIndex);
4893
+ const wordMatch = part.match(RE_WORD);
4894
+ if (wordMatch) {
4895
+ return wordMatch[0];
4896
+ }
4897
+ return '';
4898
+ };
4899
+ const handleEditorType = (editorUid, state, text) => {
4900
+ const editor = getEditor(editorUid);
4901
+ const {
4902
+ unfilteredItems,
4903
+ itemHeight,
4904
+ maxHeight
4905
+ } = state;
4906
+ const rowIndex = editor.selections[0];
4907
+ const columnIndex = editor.selections[1];
4908
+ const x$1 = x(editor, rowIndex, columnIndex);
4909
+ // @ts-ignore
4910
+ const y$1 = y(editor, rowIndex);
4911
+ const wordAtOffset = getWordAtOffset(editor);
4912
+ const items = filterCompletionItems(unfilteredItems, wordAtOffset);
4913
+ const newMinLineY = 0;
4914
+ const newMaxLineY = Math.min(items.length, 8);
4915
+ const height = getListHeight(items.length, itemHeight, maxHeight);
4916
+ const finalDeltaY = items.length * itemHeight - height;
4917
+ return {
4918
+ ...state,
4919
+ items,
4920
+ x: x$1,
4921
+ y: y$1,
4922
+ minLineY: newMinLineY,
4923
+ maxLineY: newMaxLineY,
4924
+ leadingWord: wordAtOffset,
4925
+ height,
4926
+ finalDeltaY
4927
+ };
4928
+ };
4929
+ const handleEditorDeleteLeft = (editorUid, state) => {
4930
+ const editor = getEditor(editorUid);
4931
+ const {
4932
+ unfilteredItems,
4933
+ itemHeight,
4934
+ maxHeight
4935
+ } = state;
4936
+ const rowIndex = editor.selections[0];
4937
+ const columnIndex = editor.selections[1];
4938
+ const x$1 = x(editor, rowIndex, columnIndex);
4939
+ // @ts-ignore
4940
+ const y$1 = y(editor, rowIndex);
4941
+ const wordAtOffset = getWordAtOffset(editor);
4942
+ if (!wordAtOffset) {
4943
+ editor.completionState = None$1;
4944
+ return {
4945
+ ...state,
4946
+ disposed: true
4947
+ };
4948
+ }
4949
+ const items = filterCompletionItems(unfilteredItems, wordAtOffset);
4950
+ const newMaxLineY = Math.min(items.length, 8);
4951
+ const height = getListHeight(items.length, itemHeight, maxHeight);
4952
+ return {
4953
+ ...state,
4954
+ items,
4955
+ x: x$1,
4956
+ y: y$1,
4957
+ maxLineY: newMaxLineY,
4958
+ leadingWord: wordAtOffset,
4959
+ height
4960
+ };
4961
+ };
4962
+ const dispose = state => {
4963
+ return {
4964
+ ...state,
4965
+ disposed: true
4966
+ };
4967
+ };
4968
+ const disposeWithEditor = (state, editor) => {
4969
+ editor.completionState = None$1;
4970
+ editor.completionUid = 0;
4971
+ // Focus.removeAdditionalFocus(FocusKey.EditorCompletion)
4972
+ return dispose(state);
4973
+ };
4974
+ const handleEditorClick = disposeWithEditor;
4975
+ const handleEditorBlur = disposeWithEditor;
4976
+ const loadContent$2 = async (editorUid, state) => {
4977
+ const editor = getEditor(editorUid);
4978
+ const {
4979
+ itemHeight,
4980
+ maxHeight
4981
+ } = state;
4982
+ const unfilteredItems = await getCompletions(editor);
4983
+ const wordAtOffset = getWordAtOffset(editor);
4984
+ const items = filterCompletionItems(unfilteredItems, wordAtOffset);
4985
+ const rowIndex = editor.selections[0];
4986
+ const columnIndex = editor.selections[1];
4987
+ const x$1 = x(editor, rowIndex, columnIndex);
4988
+ // @ts-ignore
4989
+ const y$1 = y(editor, rowIndex);
4990
+ const newMaxLineY = Math.min(items.length, 8);
4991
+ editor.widgets = editor.widgets || [];
4992
+ // editor.widgets.push(ViewletModuleId.EditorCompletion)
4993
+ const itemsLength = items.length;
4994
+ const newFocusedIndex = itemsLength === 0 ? -1 : 0;
4995
+ const total = items.length;
4996
+ const height = getListHeight(items.length, itemHeight, maxHeight);
4997
+ const finalDeltaY = getFinalDeltaY(height, itemHeight, total);
4998
+ return {
4999
+ ...state,
5000
+ unfilteredItems,
5001
+ items,
5002
+ x: x$1,
5003
+ y: y$1,
5004
+ maxLineY: newMaxLineY,
5005
+ focusedIndex: newFocusedIndex,
5006
+ finalDeltaY,
5007
+ leadingWord: wordAtOffset,
5008
+ height,
5009
+ rowIndex,
5010
+ columnIndex,
5011
+ editorUid,
5012
+ width: 200
5013
+ };
5014
+ };
5015
+ const advance = (state, word) => {
5016
+ const filteredItems = filterCompletionItems(state.items, word);
5017
+ return {
5018
+ ...state,
5019
+ filteredItems
5020
+ };
5021
+ };
5022
+
5023
+ const openCompletion = async editor => {
5024
+ const {
5025
+ widgets,
5026
+ uid
5027
+ } = editor;
5028
+ const completionUid = Math.random();
5029
+ const completionWidget = {
5030
+ id: 'completion',
5031
+ oldState: {
5032
+ items: [],
5033
+ itemHeight: 20,
5034
+ maxHeight: 150,
5035
+ minLineY: 0,
5036
+ maxLineY: 0,
5037
+ uid: completionUid
5038
+ },
5039
+ newState: {
5040
+ items: [],
5041
+ itemHeight: 20,
5042
+ maxHeight: 150,
5043
+ minLineY: 0,
5044
+ maxLineY: 10,
5045
+ uid: completionUid
5046
+ }
5047
+ };
5048
+ const newWidgets = [...widgets, completionWidget];
5049
+ const newEditor = {
5050
+ ...editor,
5051
+ widgets: newWidgets
5052
+ };
5053
+ set$6(uid, editor, newEditor);
5054
+ const newCompletionWidget = await loadContent$2(uid, completionWidget.newState);
5055
+ const FocusEditorCompletions = 9;
5056
+ await invoke$3('Focus.setAdditionalFocus', FocusEditorCompletions);
5057
+ const latestEditor = getEditor(uid);
5058
+ if (!latestEditor.widgets.includes(completionWidget)) {
5059
+ return editor;
5060
+ }
5061
+ const index = latestEditor.widgets.indexOf(completionWidget);
5062
+ const latestWidgets = [...latestEditor.widgets.slice(0, index), {
5063
+ ...completionWidget,
5064
+ newState: newCompletionWidget
5065
+ }, ...latestEditor.widgets.slice(index + 1)];
5066
+ return {
5067
+ ...latestEditor,
5068
+ widgets: latestWidgets
5069
+ };
5070
+ };
5071
+
5072
+ const FindWidget = 'FindWidget';
5073
+ const openFind = async state => {
5074
+ await invoke$3('Viewlet.openWidget', FindWidget);
5075
+ return state;
5076
+ };
5077
+
5078
+ const organizeImports = async editor => {
5079
+ // TODO ask extension host worker directly
5080
+ const edits = await invoke$3('ExtensionHostOrganizeImports.organizeImports', editor);
5081
+ console.log({
5082
+ edits
5083
+ });
5084
+ return applyDocumentEdits(editor, edits);
5085
+ };
5086
+
5087
+ // @ts-ignore
5088
+
5089
+ // @ts-ignore
5090
+ const pasteText = (editor, text) => {
5091
+ const insertedLines = splitLines$2(text);
5092
+ const changes = editorReplaceSelections(editor, insertedLines, EditorPasteText);
5093
+ return scheduleDocumentAndCursorsSelections(editor, changes);
5094
+ };
5095
+
5096
+ const paste = async editor => {
5097
+ const text = await invoke$3('ClipBoard.readText');
5098
+ string(text);
5099
+ return pasteText(editor, text);
5100
+ };
5101
+
5102
+ const getErrorMessage$1 = error => {
5103
+ if (!error) {
5104
+ return `Error: ${error}`;
5105
+ }
5106
+ let message = error.message;
5107
+ while (error.cause) {
5108
+ error = error.cause;
5109
+ message += `: ${error}`;
5110
+ }
5111
+ return message;
5112
+ };
5113
+ const prepareErrorMessageWithCodeFrame = error => {
5114
+ if (!error) {
5115
+ return {
5116
+ message: error,
5117
+ stack: undefined,
5118
+ codeFrame: undefined,
5119
+ type: 'Error'
5120
+ };
5121
+ }
5122
+ const message = getErrorMessage$1(error);
5123
+ if (error.codeFrame) {
5124
+ return {
5125
+ message,
5126
+ stack: error.stack,
5127
+ codeFrame: error.codeFrame,
5128
+ type: error.constructor.name
5129
+ };
5130
+ }
5131
+ return {
5132
+ message,
5133
+ stack: error.originalStack,
5134
+ codeFrame: error.originalCodeFrame,
5135
+ category: error.category,
5136
+ stderr: error.stderr
5137
+ };
5138
+ };
5139
+ const RE_PATH_1 = /\((.*):(\d+):(\d+)\)$/;
5140
+ const RE_PATH_2 = /at (.*):(\d+):(\d+)$/;
5141
+
5142
+ /**
5143
+ *
5144
+ * @param {readonly string[]} lines
5145
+ * @returns
5146
+ */
5147
+ const getFile = lines => {
5148
+ for (const line of lines) {
5149
+ if (RE_PATH_1.test(line) || RE_PATH_2.test(line)) {
5150
+ return line;
5151
+ }
5152
+ }
5153
+ return '';
5154
+ };
5155
+ const prepareErrorMessageWithoutCodeFrame = async error => {
5156
+ try {
5157
+ const lines = splitLines$2(error.stack);
5158
+ const file = getFile(lines);
5159
+ let match = file.match(RE_PATH_1);
5160
+ if (!match) {
5161
+ match = file.match(RE_PATH_2);
5162
+ }
5163
+ if (!match) {
5164
+ return error;
5165
+ }
5166
+ const relevantStack = joinLines$2(lines.slice(1));
5167
+ const message = getErrorMessage$1(error);
5168
+ return {
5169
+ message,
5170
+ stack: relevantStack,
5171
+ type: error.constructor.name
5172
+ };
5173
+ } catch (otherError) {
5174
+ console.warn('ErrorHandling Error');
5175
+ console.warn(otherError);
5176
+ return error;
5177
+ }
5178
+ };
5179
+ const prepare = async error => {
5180
+ if (error && error.message && error.codeFrame) {
5181
+ return prepareErrorMessageWithCodeFrame(error);
5182
+ }
5183
+ if (error && error.stack) {
5184
+ return prepareErrorMessageWithoutCodeFrame(error);
5185
+ }
5186
+ return error;
5187
+ };
5188
+ const print = error => {
5189
+ if (error && error.type && error.message && error.codeFrame) {
5190
+ return `${error.type}: ${error.message}\n\n${error.codeFrame}\n\n${error.stack}`;
5191
+ }
5192
+ if (error && error.message && error.codeFrame) {
5193
+ return `${error.message}\n\n${error.codeFrame}\n\n${error.stack}`;
5194
+ }
5195
+ if (error && error.type && error.message) {
5196
+ return `${error.type}: ${error.message}\n${error.stack}`;
5197
+ }
5198
+ if (error && error.stack) {
5199
+ return `${error.stack}`;
5200
+ }
5201
+ if (error === null) {
5202
+ return null;
5203
+ }
5204
+ return `${error}`;
5205
+ };
5206
+
5207
+ // @ts-nocheck
5208
+ const logError = async error => {
5209
+ const prettyError = await prepare(error);
5210
+ const prettyErrorString = print(prettyError);
5211
+ console.error(prettyErrorString);
5212
+ return prettyError;
5213
+ };
5214
+ const handleError = async error => {
5215
+ try {
5216
+ const prettyError = await logError(error);
5217
+ } catch (otherError) {
5218
+ console.warn('ErrorHandling error');
5219
+ console.warn(otherError);
5220
+ console.error(error);
5221
+ }
5222
+ };
5223
+
5224
+ // @ts-ignore
5225
+ const getNewEditor = async editor => {
5226
+ return editor;
4640
5227
  };
4641
5228
 
4642
5229
  // @ts-ignore
@@ -6195,518 +6782,504 @@ const editorUnindent = editor => {
6195
6782
 
6196
6783
  // editor.lines //?
6197
6784
 
6198
- const OnCompletion = 'onCompletion';
6199
- const OnHover = 'onHover';
6200
-
6201
- // TODO add tests for this
6202
- const activateByEvent = async event => {
6203
- await invoke$3('ExtensionHostManagement.activateByEvent', event);
6785
+ const isCompletion$2 = widget => {
6786
+ return widget.id === 'completion';
6204
6787
  };
6205
-
6206
- const execute = async ({
6207
- editor,
6208
- args,
6209
- event,
6210
- method,
6211
- noProviderFoundMessage,
6212
- noProviderFoundResult = undefined
6213
- }) => {
6214
- const fullEvent = `${event}:${editor.languageId}`;
6215
- await activateByEvent(fullEvent);
6216
- const result = await invoke$2(method, editor.uid, ...args);
6217
- return result;
6788
+ const getCompletionState = editor => {
6789
+ const {
6790
+ widgets
6791
+ } = editor;
6792
+ const child = widgets.find(isCompletion$2);
6793
+ return child.newState;
6218
6794
  };
6219
6795
 
6220
- const combineResults = results => {
6221
- return results[0] ?? [];
6796
+ const isCompletion$1 = widget => {
6797
+ return widget.id === 'completion';
6222
6798
  };
6223
- const executeCompletionProvider = (editor, offset) => {
6224
- return execute({
6225
- editor,
6226
- event: OnCompletion,
6227
- method: CompletionExecute,
6228
- args: [offset],
6229
- noProviderFoundMessage: 'no completion provider found',
6230
- noProviderFoundResult: [],
6231
- combineResults
6232
- });
6799
+ const focusIndex$1 = (editor, index) => {
6800
+ const child = getCompletionState(editor);
6801
+ if (index === -1) {
6802
+ return editor;
6803
+ }
6804
+ const childIndex = editor.widgets.findIndex(isCompletion$1);
6805
+ // TODO scroll up/down if necessary
6806
+ const childWidget = editor.widgets[childIndex];
6807
+ const newWidget = {
6808
+ ...childWidget,
6809
+ newState: {
6810
+ ...child,
6811
+ focusedIndex: index,
6812
+ focused: true
6813
+ }
6814
+ };
6815
+ const newWidgets = [...editor.widgets.slice(0, childIndex), newWidget, ...editor.widgets.slice(childIndex + 1)];
6816
+ return {
6817
+ ...editor,
6818
+ widgets: newWidgets
6819
+ };
6233
6820
  };
6234
- const combineResultsResolve = items => {
6235
- return items[0] ?? undefined;
6821
+
6822
+ const focusFirst$1 = editor => {
6823
+ const firstIndex = 0;
6824
+ return focusIndex$1(editor, firstIndex);
6236
6825
  };
6237
- const executeResolveCompletionItem = (editor, offset, name, completionItem) => {
6238
- return execute({
6239
- editor,
6240
- event: OnCompletion,
6241
- method: CompletionResolveExecute,
6242
- args: [offset, name, completionItem],
6243
- noProviderFoundMessage: 'no completion provider found',
6244
- noProviderFoundResult: [],
6245
- combineResults: combineResultsResolve
6246
- });
6826
+
6827
+ const focusNext$1 = editor => {
6828
+ const child = getCompletionState(editor);
6829
+ const nextIndex = child.focusedIndex + 1;
6830
+ return focusIndex$1(editor, nextIndex);
6247
6831
  };
6248
6832
 
6249
- // TODO possible to do this with events/state machine instead of promises -> enables canceling operations / concurrent calls
6250
- const getCompletions = async editor => {
6833
+ const focusPrevious$1 = editor => {
6834
+ const child = getCompletionState(editor);
6835
+ const previousIndex = child.focusedIndex - 1;
6836
+ return focusIndex$1(editor, previousIndex);
6837
+ };
6838
+
6839
+ const getEdits = async (editor, completionItem) => {
6840
+ const child = getCompletionState(editor);
6841
+ // @ts-ignore
6842
+ const {
6843
+ leadingWord,
6844
+ uid
6845
+ } = child;
6846
+ const word = completionItem.label;
6847
+ const resolvedItem = await resolveCompletion(editor, word, completionItem);
6848
+ const inserted = resolvedItem ? resolvedItem.snippet : word;
6849
+ // TODO type and dispose commands should be sent to renderer process at the same time
6251
6850
  const {
6252
6851
  selections
6253
6852
  } = editor;
6254
- const rowIndex = selections[0];
6255
- const columnIndex = selections[1];
6256
- // Editor.sync(editor)
6257
- const offset = await offsetAt(editor, rowIndex, columnIndex);
6258
- const completions = await executeCompletionProvider(editor, offset);
6259
- return completions;
6853
+ const [startRowIndex, startColumnIndex] = selections;
6854
+ const leadingWordLength = leadingWord.length;
6855
+ const replaceRange$1 = new Uint32Array([startRowIndex, startColumnIndex - leadingWordLength, startRowIndex, startColumnIndex]);
6856
+ const changes = replaceRange(editor, replaceRange$1, [inserted], '');
6857
+ return changes;
6260
6858
  };
6261
-
6262
- // TODO don't send unnecessary parts of completion item like matches
6263
- const resolveCompletion = async (editor, name, completionItem) => {
6264
- try {
6265
- object(editor);
6266
- string(name);
6267
- object(completionItem);
6268
- const rowIndex = editor.selections[0];
6269
- const columnIndex = editor.selections[1];
6270
- const offset = await offsetAt(editor, rowIndex, columnIndex);
6271
- // @ts-ignore
6272
- const resolvedCompletionItem = await executeResolveCompletionItem(editor, offset, name, completionItem);
6273
- return resolvedCompletionItem;
6274
- } catch {
6275
- return undefined;
6859
+ const isCompletion = widget => {
6860
+ return widget.id === 'completion';
6861
+ };
6862
+ const select = async (editor, completionItem) => {
6863
+ const changes = await getEdits(editor, completionItem);
6864
+ const index = editor.widgets.indexOf
6865
+ // ViewletModuleId.EditorCompletion
6866
+ ();
6867
+ if (index !== -1) {
6868
+ editor.widgets.splice(index, 1);
6869
+ editor.completionState = None$1;
6870
+ editor.completionUid = 0;
6871
+ }
6872
+ // TODO dispose completion widget
6873
+ // TODO apply edit in editor worker instead of asking renderer worker
6874
+ // await RendererWorker.invoke('Viewlet.dispose', state.uid)
6875
+ const {
6876
+ widgets
6877
+ } = editor;
6878
+ const completionWidgetIndex = editor.widgets.findIndex(isCompletion);
6879
+ const newWidgets = [...widgets.slice(0, completionWidgetIndex), ...widgets.slice(completionWidgetIndex + 1)];
6880
+ const intermediateEditor = await applyEdit(editor, changes);
6881
+ return {
6882
+ ...intermediateEditor,
6883
+ widgets: newWidgets
6884
+ };
6885
+ };
6886
+ const selectIndex = (editor, index) => {
6887
+ const child = getCompletionState(editor);
6888
+ const {
6889
+ items
6890
+ } = child;
6891
+ if (index === -1) {
6892
+ return editor;
6893
+ }
6894
+ if (index > items.length) {
6895
+ throw new Error('index too large');
6276
6896
  }
6897
+ const actualIndex = index;
6898
+ const completionItem = items[actualIndex];
6899
+ return select(editor, completionItem);
6277
6900
  };
6278
6901
 
6279
- const None$1 = 1;
6280
-
6281
- const EmptyMatches = [];
6902
+ const selectCurrent = editor => {
6903
+ const child = getCompletionState(editor);
6904
+ const {
6905
+ focusedIndex
6906
+ } = child;
6907
+ return selectIndex(editor, focusedIndex);
6908
+ };
6282
6909
 
6283
- const Diagonal = 1;
6284
- const Left = 2;
6910
+ const executeHoverProvider = (editor, offset) => {
6911
+ object(editor);
6912
+ number$1(offset);
6913
+ return execute({
6914
+ event: OnHover,
6915
+ editor,
6916
+ method: HoverExecute,
6917
+ args: [offset],
6918
+ noProviderFoundMessage: 'No hover provider found'
6919
+ });
6920
+ };
6285
6921
 
6286
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
6922
+ const getHover = async (editor, offset) => {
6923
+ object(editor);
6924
+ number$1(offset);
6925
+ // TODO invoke extension host worker directly
6926
+ const hover = await executeHoverProvider(editor, offset);
6927
+ return hover;
6928
+ };
6287
6929
 
6288
- const createTable = size => {
6289
- const table = [];
6290
- for (let i = 0; i < size; i++) {
6291
- const row = new Uint8Array(size);
6292
- table.push(row);
6293
- }
6294
- return table;
6930
+ let _ipc;
6931
+ const listen$5 = async () => {
6932
+ const ipc = await create$1({
6933
+ method: RendererProcess
6934
+ });
6935
+ handleIpc(ipc);
6936
+ _ipc = ipc;
6295
6937
  };
6296
-
6297
- const isLowerCase = char => {
6298
- return char === char.toLowerCase();
6938
+ const invoke = async (method, ...args) => {
6939
+ return invoke$5(_ipc, method, ...args);
6299
6940
  };
6300
6941
 
6301
- const isUpperCase = char => {
6302
- return char === char.toUpperCase();
6942
+ const measureTextBlockHeight = (text, fontFamily, fontSize, lineHeight, width) => {
6943
+ return invoke('MeasureTextBlockHeight.measureTextBlockHeight', text, fontSize, fontFamily, lineHeight, width);
6303
6944
  };
6304
6945
 
6305
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
6306
- const isGap = (columnCharBefore, columnChar) => {
6307
- switch (columnCharBefore) {
6308
- case Dash:
6309
- case Underline:
6310
- case EmptyString:
6311
- case T:
6312
- case Space:
6313
- case Dot:
6314
- return true;
6315
- }
6316
- if (isLowerCase(columnCharBefore) && isUpperCase(columnChar)) {
6317
- return true;
6318
- }
6319
- return false;
6946
+ const deepCopy = value => {
6947
+ return structuredClone(value);
6320
6948
  };
6321
6949
 
6322
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
6323
- const getScore = (rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, column, wordLength, isDiagonalMatch) => {
6324
- if (rowCharLow !== columnCharLow) {
6325
- return -1;
6326
- }
6327
- const isMatch = rowChar === columnChar;
6328
- if (isMatch) {
6329
- if (isDiagonalMatch) {
6330
- return 8;
6331
- }
6332
- if (isGap(columnCharBefore, columnChar)) {
6333
- return 8;
6334
- }
6335
- return 5;
6336
- }
6337
- if (isGap(columnCharBefore, columnChar)) {
6338
- return 8;
6339
- }
6340
- return 5;
6950
+ const getInitialLineState = initialLineState => {
6951
+ return deepCopy(initialLineState);
6341
6952
  };
6342
6953
 
6343
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
6344
-
6345
- const isPatternInWord = (patternLow, patternPos, patternLen, wordLow, wordPos, wordLen) => {
6346
- while (patternPos < patternLen && wordPos < wordLen) {
6347
- if (patternLow[patternPos] === wordLow[wordPos]) {
6348
- patternPos += 1;
6349
- }
6350
- wordPos += 1;
6954
+ const getLineInfo$1 = (line, tokens, TokenMap) => {
6955
+ const tokensLength = tokens.length;
6956
+ let end = 0;
6957
+ let start = 0;
6958
+ const lineInfo = [];
6959
+ for (let i = 0; i < tokensLength; i += 2) {
6960
+ const tokenType = tokens[i];
6961
+ const tokenLength = tokens[i + 1];
6962
+ end += tokenLength;
6963
+ const text = line.slice(start, end);
6964
+ const className = `Token ${TokenMap[tokenType] || 'Unknown'}`;
6965
+ const normalizedText = text;
6966
+ lineInfo.push(normalizedText, className);
6967
+ start = end;
6351
6968
  }
6352
- return patternPos === patternLen; // pattern must be exhausted
6969
+ return lineInfo;
6353
6970
  };
6354
6971
 
6355
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
6356
- const traceHighlights = (table, arrows, patternLength, wordLength) => {
6357
- let row = patternLength;
6358
- let column = wordLength;
6359
- const matches = [];
6360
- while (row >= 1 && column >= 1) {
6361
- const arrow = arrows[row][column];
6362
- if (arrow === Left) {
6363
- column--;
6364
- } else if (arrow === Diagonal) {
6365
- row--;
6366
- column--;
6367
- const start = column + 1;
6368
- while (row >= 1 && column >= 1) {
6369
- const arrow = arrows[row][column];
6370
- if (arrow === Left) {
6371
- break;
6372
- }
6373
- if (arrow === Diagonal) {
6374
- row--;
6375
- column--;
6376
- }
6377
- }
6378
- const end = column;
6379
- matches.unshift(end, start);
6380
- }
6381
- }
6382
- matches.unshift(table[patternLength][wordLength - 1]);
6383
- return matches;
6972
+ const state = {
6973
+ warned: []
6384
6974
  };
6385
-
6386
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
6387
- const gridSize = 128;
6388
- const table = createTable(gridSize);
6389
- const arrows = createTable(gridSize);
6390
- // @ts-ignore
6391
- createTable(gridSize);
6392
- const filterCompletionItem = (pattern, word) => {
6393
- const patternLength = Math.min(pattern.length, gridSize - 1);
6394
- const wordLength = Math.min(word.length, gridSize - 1);
6395
- const patternLower = pattern.toLowerCase();
6396
- const wordLower = word.toLowerCase();
6397
- if (!isPatternInWord(patternLower, 0, patternLength, wordLower, 0, wordLength)) {
6398
- return EmptyMatches;
6399
- }
6400
- let strongMatch = false;
6401
- for (let row = 1; row < patternLength + 1; row++) {
6402
- const rowChar = pattern[row - 1];
6403
- const rowCharLow = patternLower[row - 1];
6404
- for (let column = 1; column < wordLength + 1; column++) {
6405
- const columnChar = word[column - 1];
6406
- const columnCharLow = wordLower[column - 1];
6407
- const columnCharBefore = word[column - 2] || '';
6408
- const isDiagonalMatch = arrows[row - 1][column - 1] === Diagonal;
6409
- const score = getScore(rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, column, wordLength, isDiagonalMatch);
6410
- if (row === 1 && score > 5) {
6411
- strongMatch = true;
6412
- }
6413
- let diagonalScore = score + table[row - 1][column - 1];
6414
- if (isDiagonalMatch && score !== -1) {
6415
- diagonalScore += 2;
6416
- }
6417
- const leftScore = table[row][column - 1];
6418
- if (leftScore > diagonalScore) {
6419
- table[row][column] = leftScore;
6420
- arrows[row][column] = Left;
6421
- } else {
6422
- table[row][column] = diagonalScore;
6423
- arrows[row][column] = Diagonal;
6424
- }
6425
- }
6426
- }
6427
- if (!strongMatch) {
6428
- return EmptyMatches;
6975
+ const flattenTokensArray = tokens => {
6976
+ const flattened = [];
6977
+ for (const token of tokens) {
6978
+ object(token);
6979
+ flattened.push(token.type, token.length);
6429
6980
  }
6430
- // printTables(pattern, 0, word, 0)
6431
- const highlights = traceHighlights(table, arrows, patternLength, wordLength);
6432
- return highlights;
6433
- };
6434
-
6435
- const Deprecated = 1 << 0;
6436
-
6437
- const addEmptyMatch = item => {
6438
- return {
6439
- ...item,
6440
- matches: EmptyMatches
6441
- };
6981
+ return flattened;
6442
6982
  };
6443
- const filterCompletionItems = (completionItems, word) => {
6444
- if (word === EmptyString) {
6445
- return completionItems.map(addEmptyMatch);
6983
+ const warnDeprecatedArrayReturn = (languageId, fn) => {
6984
+ if (state.warned.includes(fn)) {
6985
+ return;
6446
6986
  }
6447
- const filteredCompletions = [];
6448
- const deprecated = [];
6449
- for (const completionItem of completionItems) {
6450
- const {
6451
- label,
6452
- flags
6453
- } = completionItem;
6454
- const result = filterCompletionItem(word, label);
6455
- if (result !== EmptyMatches) {
6456
- if (flags & Deprecated) {
6457
- // TODO avoid mutation
6458
- completionItem.matches = EmptyMatches;
6459
- deprecated.push(completionItem);
6460
- } else {
6461
- // TODO avoid mutation
6462
- completionItem.matches = result;
6463
- filteredCompletions.push(completionItem);
6464
- }
6987
+ state.warned.push(fn);
6988
+ console.warn(`tokenizers without hasArrayReturn=false are deprecated (language ${languageId})`);
6989
+ };
6990
+ const safeTokenizeLine = (languageId, tokenizeLine, line, lineStateAtStart, hasArrayReturn) => {
6991
+ try {
6992
+ const lineState = tokenizeLine(line, lineStateAtStart);
6993
+ if (!lineState || !lineState.tokens || !lineState.state) {
6994
+ throw new Error('invalid tokenization result');
6465
6995
  }
6996
+ if (!hasArrayReturn) {
6997
+ warnDeprecatedArrayReturn(languageId, tokenizeLine);
6998
+ // workaround for old tokenizers
6999
+ lineState.tokens = flattenTokensArray(lineState.tokens);
7000
+ }
7001
+ return lineState;
7002
+ } catch (error) {
7003
+ console.error(error);
7004
+ return {
7005
+ tokens: [/* type */0, /* length */line.length],
7006
+ lineState: lineStateAtStart
7007
+ };
6466
7008
  }
6467
- if (deprecated.length > 0) {
6468
- filteredCompletions.push(...deprecated);
6469
- }
6470
- return filteredCompletions;
6471
- };
6472
-
6473
- const getFinalDeltaY = (height, itemHeight, itemsLength) => {
6474
- const contentHeight = itemsLength * itemHeight;
6475
- const finalDeltaY = Math.max(contentHeight - height, 0);
6476
- return finalDeltaY;
6477
7009
  };
6478
7010
 
6479
- const getListHeight = (itemsLength, itemHeight, maxHeight) => {
6480
- number$1(itemsLength);
6481
- number$1(itemHeight);
6482
- number$1(maxHeight);
6483
- if (itemsLength === 0) {
6484
- return itemHeight;
7011
+ const getLineInfos = (lines, tokenizer, languageId) => {
7012
+ const lineInfos = [];
7013
+ const {
7014
+ tokenizeLine,
7015
+ initialLineState,
7016
+ hasArrayReturn,
7017
+ TokenMap
7018
+ } = tokenizer;
7019
+ let currentLineState = getInitialLineState(initialLineState);
7020
+ for (const line of lines) {
7021
+ const result = safeTokenizeLine(languageId, tokenizeLine, line, currentLineState, hasArrayReturn);
7022
+ const {
7023
+ tokens
7024
+ } = result;
7025
+ const lineInfo = getLineInfo$1(line, tokens, TokenMap);
7026
+ lineInfos.push(lineInfo);
7027
+ currentLineState = result;
6485
7028
  }
6486
- const totalHeight = itemsLength * itemHeight;
6487
- return Math.min(totalHeight, maxHeight);
7029
+ return lineInfos;
6488
7030
  };
6489
7031
 
6490
- const RE_WORD = /[\w\-]+$/;
6491
- const getWordAtOffset = editor => {
6492
- const {
6493
- lines,
6494
- selections
6495
- } = editor;
7032
+ const tokenizeCodeBlock = async (codeBlock, languageId, tokenizerPath) => {
7033
+ await loadTokenizer(languageId, tokenizerPath);
7034
+ const tokenizer = getTokenizer(languageId);
7035
+ const lines = splitLines$2(codeBlock);
7036
+ const lineInfos = getLineInfos(lines, tokenizer, languageId);
7037
+ return lineInfos;
7038
+ };
7039
+
7040
+ const getHoverPosition = (position, selections) => {
7041
+ if (position) {
7042
+ return position;
7043
+ }
6496
7044
  const rowIndex = selections[0];
6497
7045
  const columnIndex = selections[1];
6498
- const line = lines[rowIndex];
6499
- const part = line.slice(0, columnIndex);
6500
- const wordMatch = part.match(RE_WORD);
6501
- if (wordMatch) {
6502
- return wordMatch[0];
7046
+ return {
7047
+ rowIndex,
7048
+ columnIndex
7049
+ };
7050
+ };
7051
+ const getMatchingDiagnostics = (diagnostics, rowIndex, columnIndex) => {
7052
+ const matching = [];
7053
+ for (const diagnostic of diagnostics) {
7054
+ if (diagnostic.rowIndex === rowIndex) {
7055
+ matching.push(diagnostic);
7056
+ }
6503
7057
  }
6504
- return '';
7058
+ return matching;
6505
7059
  };
6506
- const handleEditorType = (editorUid, state, text) => {
6507
- const editor = getEditor(editorUid);
6508
- const {
6509
- unfilteredItems,
6510
- itemHeight,
6511
- maxHeight
6512
- } = state;
6513
- const rowIndex = editor.selections[0];
6514
- const columnIndex = editor.selections[1];
6515
- const x$1 = x(editor, rowIndex, columnIndex);
6516
- // @ts-ignore
6517
- const y$1 = y(editor, rowIndex);
6518
- const wordAtOffset = getWordAtOffset(editor);
6519
- const items = filterCompletionItems(unfilteredItems, wordAtOffset);
6520
- const newMinLineY = 0;
6521
- const newMaxLineY = Math.min(items.length, 8);
6522
- const height = getListHeight(items.length, itemHeight, maxHeight);
6523
- const finalDeltaY = items.length * itemHeight - height;
7060
+ const fallbackDisplayStringLanguageId = 'typescript'; // TODO remove this
7061
+
7062
+ const hoverDocumentationFontSize = 15;
7063
+ const hoverDocumentationFontFamily = 'Fira Code';
7064
+ const hoverDocumentationLineHeight = '1.33333';
7065
+ const hoverBorderLeft = 1;
7066
+ const hoverBorderRight = 1;
7067
+ const hoverPaddingLeft = 8;
7068
+ const hoverPaddingRight = 8;
7069
+ const hovverFullWidth = 400;
7070
+ const hoverDocumentationWidth = hovverFullWidth - hoverPaddingLeft - hoverPaddingRight - hoverBorderLeft - hoverBorderRight;
7071
+ const getHoverPositionXy = (editor, rowIndex, wordStart, documentationHeight) => {
7072
+ const x$1 = x(editor, rowIndex, wordStart);
7073
+ const y$1 = editor.height - y(editor, rowIndex) + editor.y + 40;
6524
7074
  return {
6525
- ...state,
6526
- items,
6527
7075
  x: x$1,
6528
- y: y$1,
6529
- minLineY: newMinLineY,
6530
- maxLineY: newMaxLineY,
6531
- leadingWord: wordAtOffset,
6532
- height,
6533
- finalDeltaY
7076
+ y: y$1
6534
7077
  };
6535
7078
  };
6536
- const handleEditorDeleteLeft = (editorUid, state) => {
6537
- const editor = getEditor(editorUid);
7079
+ const getEditorHoverInfo = async (editorUid, position) => {
7080
+ number$1(editorUid);
7081
+ const instance = get$6(editorUid);
7082
+ const editor = instance.newState;
6538
7083
  const {
6539
- unfilteredItems,
6540
- itemHeight,
6541
- maxHeight
6542
- } = state;
6543
- const rowIndex = editor.selections[0];
6544
- const columnIndex = editor.selections[1];
6545
- const x$1 = x(editor, rowIndex, columnIndex);
6546
- // @ts-ignore
6547
- const y$1 = y(editor, rowIndex);
6548
- const wordAtOffset = getWordAtOffset(editor);
6549
- if (!wordAtOffset) {
6550
- editor.completionState = None$1;
6551
- return {
6552
- ...state,
6553
- disposed: true
6554
- };
7084
+ selections
7085
+ } = editor;
7086
+ const {
7087
+ rowIndex,
7088
+ columnIndex
7089
+ } = getHoverPosition(position, selections);
7090
+ const offset = offsetAt(editor, rowIndex, columnIndex);
7091
+ const hover = await getHover(editor, offset);
7092
+ if (!hover) {
7093
+ return undefined;
6555
7094
  }
6556
- const items = filterCompletionItems(unfilteredItems, wordAtOffset);
6557
- const newMaxLineY = Math.min(items.length, 8);
6558
- const height = getListHeight(items.length, itemHeight, maxHeight);
7095
+ const {
7096
+ displayString,
7097
+ documentation,
7098
+ displayStringLanguageId
7099
+ } = hover;
7100
+ const tokenizerPath = '';
7101
+ const lineInfos = await tokenizeCodeBlock(displayString, displayStringLanguageId || fallbackDisplayStringLanguageId, tokenizerPath);
7102
+ const wordPart = await getWordBefore(editor, rowIndex, columnIndex);
7103
+ const wordStart = columnIndex - wordPart.length;
7104
+ await measureTextBlockHeight(documentation, hoverDocumentationFontFamily, hoverDocumentationFontSize, hoverDocumentationLineHeight, hoverDocumentationWidth);
7105
+ const {
7106
+ x,
7107
+ y
7108
+ } = getHoverPositionXy(editor, rowIndex, wordStart);
7109
+ const diagnostics = editor.diagnostics || [];
7110
+ const matchingDiagnostics = getMatchingDiagnostics(diagnostics, rowIndex);
6559
7111
  return {
6560
- ...state,
6561
- items,
6562
- x: x$1,
6563
- y: y$1,
6564
- maxLineY: newMaxLineY,
6565
- leadingWord: wordAtOffset,
6566
- height
7112
+ lineInfos,
7113
+ documentation,
7114
+ x,
7115
+ y,
7116
+ matchingDiagnostics
6567
7117
  };
6568
7118
  };
6569
- const dispose = state => {
7119
+
7120
+ const loadContent$1 = async (editorUid, state, position) => {
7121
+ const hoverInfo = await getEditorHoverInfo(editorUid, position);
7122
+ if (!hoverInfo) {
7123
+ return state;
7124
+ }
7125
+ const {
7126
+ lineInfos,
7127
+ documentation,
7128
+ x,
7129
+ y,
7130
+ matchingDiagnostics
7131
+ } = hoverInfo;
6570
7132
  return {
6571
7133
  ...state,
6572
- disposed: true
7134
+ lineInfos,
7135
+ documentation,
7136
+ x,
7137
+ y,
7138
+ diagnostics: matchingDiagnostics
6573
7139
  };
6574
7140
  };
6575
- const disposeWithEditor = (state, editor) => {
6576
- editor.completionState = None$1;
6577
- editor.completionUid = 0;
6578
- // Focus.removeAdditionalFocus(FocusKey.EditorCompletion)
6579
- return dispose(state);
7141
+ const handleSashPointerDown = (state, eventX, eventY) => {
7142
+ return state;
6580
7143
  };
6581
- const handleEditorClick = disposeWithEditor;
6582
- const handleEditorBlur = disposeWithEditor;
6583
- const loadContent$2 = async (editorUid, state) => {
6584
- const editor = getEditor(editorUid);
7144
+ const handleSashPointerMove = (state, eventX, eventY) => {
7145
+ // @ts-ignore
6585
7146
  const {
6586
- itemHeight,
6587
- maxHeight
7147
+ x,
7148
+ y
6588
7149
  } = state;
6589
- const unfilteredItems = await getCompletions(editor);
6590
- const wordAtOffset = getWordAtOffset(editor);
6591
- const items = filterCompletionItems(unfilteredItems, wordAtOffset);
6592
- const rowIndex = editor.selections[0];
6593
- const columnIndex = editor.selections[1];
6594
- const x$1 = x(editor, rowIndex, columnIndex);
6595
- // @ts-ignore
6596
- const y$1 = y(editor, rowIndex);
6597
- const newMaxLineY = Math.min(items.length, 8);
6598
- editor.widgets = editor.widgets || [];
6599
- // editor.widgets.push(ViewletModuleId.EditorCompletion)
6600
- const itemsLength = items.length;
6601
- const newFocusedIndex = itemsLength === 0 ? -1 : 0;
6602
- const total = items.length;
6603
- const height = getListHeight(items.length, itemHeight, maxHeight);
6604
- const finalDeltaY = getFinalDeltaY(height, itemHeight, total);
6605
- return {
6606
- ...state,
6607
- unfilteredItems,
6608
- items,
6609
- x: x$1,
6610
- y: y$1,
6611
- maxLineY: newMaxLineY,
6612
- focusedIndex: newFocusedIndex,
6613
- finalDeltaY,
6614
- leadingWord: wordAtOffset,
6615
- height,
6616
- rowIndex,
6617
- columnIndex,
6618
- editorUid,
6619
- width: 200
6620
- };
6621
- };
6622
- const advance = (state, word) => {
6623
- const filteredItems = filterCompletionItems(state.items, word);
7150
+ const minWidth = 100;
7151
+ const newWidth = Math.max(eventX - x, minWidth);
6624
7152
  return {
6625
7153
  ...state,
6626
- filteredItems
7154
+ resizedWidth: newWidth
6627
7155
  };
6628
7156
  };
6629
-
6630
- const isCompletion$1 = widget => {
6631
- return widget.id === 'completion';
6632
- };
6633
- const getCompletionState = editor => {
6634
- const {
6635
- widgets
6636
- } = editor;
6637
- const child = widgets.find(isCompletion$1);
6638
- return child.newState;
7157
+ const handleSashPointerUp = (state, eventX, eventY) => {
7158
+ return state;
6639
7159
  };
6640
7160
 
6641
- const getEdits = async (editor, completionItem) => {
6642
- const child = getCompletionState(editor);
6643
- // @ts-ignore
6644
- const {
6645
- leadingWord,
6646
- uid
6647
- } = child;
6648
- const word = completionItem.label;
6649
- const resolvedItem = await resolveCompletion(editor, word, completionItem);
6650
- const inserted = resolvedItem ? resolvedItem.snippet : word;
6651
- // TODO type and dispose commands should be sent to renderer process at the same time
6652
- const {
6653
- selections
6654
- } = editor;
6655
- const [startRowIndex, startColumnIndex] = selections;
6656
- const leadingWordLength = leadingWord.length;
6657
- const replaceRange$1 = new Uint32Array([startRowIndex, startColumnIndex - leadingWordLength, startRowIndex, startColumnIndex]);
6658
- const changes = replaceRange(editor, replaceRange$1, [inserted], '');
6659
- return changes;
6660
- };
6661
- const isCompletion = widget => {
6662
- return widget.id === 'completion';
6663
- };
6664
- const select = async (editor, completionItem) => {
6665
- const changes = await getEdits(editor, completionItem);
6666
- const index = editor.widgets.indexOf
6667
- // ViewletModuleId.EditorCompletion
6668
- ();
6669
- if (index !== -1) {
6670
- editor.widgets.splice(index, 1);
6671
- editor.completionState = None$1;
6672
- editor.completionUid = 0;
6673
- }
6674
- // TODO dispose completion widget
6675
- // TODO apply edit in editor worker instead of asking renderer worker
6676
- // await RendererWorker.invoke('Viewlet.dispose', state.uid)
6677
- const {
6678
- widgets
6679
- } = editor;
6680
- const completionWidgetIndex = editor.widgets.findIndex(isCompletion);
6681
- const newWidgets = [...widgets.slice(0, completionWidgetIndex), ...widgets.slice(completionWidgetIndex + 1)];
6682
- const intermediateEditor = await applyEdit(editor, changes);
7161
+ const text = data => {
6683
7162
  return {
6684
- ...intermediateEditor,
6685
- widgets: newWidgets
7163
+ type: Text,
7164
+ text: data,
7165
+ childCount: 0
6686
7166
  };
6687
7167
  };
6688
- const selectIndex = (editor, index) => {
6689
- const child = getCompletionState(editor);
6690
- const {
6691
- items
6692
- } = child;
6693
- if (index === -1) {
6694
- return editor;
7168
+
7169
+ const getLineInfoVirtualDom = lineInfo => {
7170
+ const dom = [{
7171
+ type: Div,
7172
+ className: HoverEditorRow,
7173
+ childCount: lineInfo.length / 2
7174
+ }];
7175
+ for (let i = 0; i < lineInfo.length; i += 2) {
7176
+ const tokenText = lineInfo[i];
7177
+ const tokenClass = lineInfo[i + 1];
7178
+ dom.push({
7179
+ type: Span,
7180
+ className: tokenClass,
7181
+ childCount: 1
7182
+ },
7183
+ // @ts-ignore
7184
+ text(tokenText));
6695
7185
  }
6696
- if (index > items.length) {
6697
- throw new Error('index too large');
7186
+ return dom;
7187
+ };
7188
+ const getLineInfosVirtualDom = lineInfos => {
7189
+ const dom = lineInfos.flatMap(getLineInfoVirtualDom);
7190
+ return dom;
7191
+ };
7192
+
7193
+ const hoverProblemMessage = {
7194
+ type: Span,
7195
+ className: HoverProblemMessage,
7196
+ childCount: 1
7197
+ };
7198
+ const hoverProblemDetail = {
7199
+ type: Span,
7200
+ className: HoverProblemDetail,
7201
+ childCount: 1
7202
+ };
7203
+ const getChildCount = (lineInfos, documentation, diagnostics) => {
7204
+ return lineInfos.length + documentation ? 1 : 0 + (diagnostics && diagnostics.length > 0) ? 1 : 0;
7205
+ };
7206
+ const getHoverVirtualDom = (lineInfos, documentation, diagnostics) => {
7207
+ const dom = [];
7208
+ dom.push({
7209
+ type: Div,
7210
+ className: 'Viewlet EditorHover',
7211
+ childCount: getChildCount(lineInfos, documentation, diagnostics) + 1
7212
+ });
7213
+ if (diagnostics && diagnostics.length > 0) {
7214
+ dom.push({
7215
+ type: Div,
7216
+ className: `${HoverDisplayString} ${HoverProblem}`,
7217
+ childCount: diagnostics.length * 2
7218
+ });
7219
+ for (const diagnostic of diagnostics) {
7220
+ dom.push(hoverProblemMessage, text(diagnostic.message), hoverProblemDetail, text(`${diagnostic.source} (${diagnostic.code})`));
7221
+ }
6698
7222
  }
6699
- const actualIndex = index;
6700
- const completionItem = items[actualIndex];
6701
- return select(editor, completionItem);
7223
+ if (lineInfos.length > 0) {
7224
+ const lineInfosDom = getLineInfosVirtualDom(lineInfos);
7225
+ dom.push({
7226
+ type: Div,
7227
+ className: HoverDisplayString,
7228
+ childCount: lineInfos.length
7229
+ }, ...lineInfosDom);
7230
+ }
7231
+ if (documentation) {
7232
+ dom.push({
7233
+ type: Div,
7234
+ className: HoverDocumentation,
7235
+ childCount: 1
7236
+ }, text(documentation));
7237
+ }
7238
+ dom.push({
7239
+ type: Div,
7240
+ className: 'Sash SashVertical SashResize',
7241
+ childCount: 0,
7242
+ onPointerDown: HandleSashPointerDown
7243
+ });
7244
+ return dom;
6702
7245
  };
6703
7246
 
6704
- const selectCurrent = editor => {
6705
- const child = getCompletionState(editor);
6706
- const {
6707
- focusedIndex
6708
- } = child;
6709
- return selectIndex(editor, focusedIndex);
7247
+ const renderHoverDom = {
7248
+ isEqual(oldState, newState) {
7249
+ return oldState.lineInfos === newState.lineInfos && oldState.documentation === newState.documentation && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.diagnostics === newState.diagnostics;
7250
+ },
7251
+ apply(oldState, newState) {
7252
+ const dom = getHoverVirtualDom(newState.lineInfos, newState.documentation, newState.diagnostics);
7253
+ return [/* method */'Viewlet.setDom2', dom];
7254
+ }
7255
+ };
7256
+ const renderBounds$1 = {
7257
+ isEqual(oldState, newState) {
7258
+ return oldState.x === newState.x && oldState.y === newState.y && oldState.resizedWidth === newState.resizedWidth;
7259
+ },
7260
+ apply(oldState, newState) {
7261
+ // @ts-ignore
7262
+ const {
7263
+ x,
7264
+ y,
7265
+ width,
7266
+ height,
7267
+ resizedWidth,
7268
+ uid
7269
+ } = newState;
7270
+ console.log('apply');
7271
+ return [SetBounds, x, y, resizedWidth, height];
7272
+ }
7273
+ };
7274
+ const render$2 = [renderHoverDom, renderBounds$1];
7275
+ const renderHover = async (oldState, newState) => {
7276
+ const commands = [];
7277
+ for (const item of render$2) {
7278
+ if (!item.isEqual(oldState, newState)) {
7279
+ commands.push(item.apply(oldState, newState));
7280
+ }
7281
+ }
7282
+ return commands;
6710
7283
  };
6711
7284
 
6712
7285
  // copied from https://github.com/microsoft/vscode/tree/main/src/vs/base/common/strings.ts by Microsoft (License MIT)
@@ -6753,7 +7326,7 @@ const getMatchCount = matches => {
6753
7326
  return matches.length / 2;
6754
7327
  };
6755
7328
 
6756
- const loadContent$1 = editorId => {
7329
+ const loadContent = editorId => {
6757
7330
  const editor = getEditor(editorId);
6758
7331
  const {
6759
7332
  selections,
@@ -6868,264 +7441,62 @@ const setLoaded = id => {
6868
7441
  loaded[id] = true;
6869
7442
  };
6870
7443
  const isLoaded = id => {
6871
- return loaded[id];
6872
- };
6873
-
6874
- const getFonts = () => {
6875
- // @ts-ignore
6876
- return globalThis.fonts || document.fonts;
6877
- };
6878
-
6879
- const loadFont = async (fontName, fontUrl) => {
6880
- try {
6881
- string(fontName);
6882
- string(fontUrl);
6883
- if (fontName.startsWith("'")) {
6884
- throw new Error('font name is not allowed start with quotes');
6885
- }
6886
- const fontFace = new FontFace(fontName, fontUrl, {});
6887
- await fontFace.load();
6888
- const fonts = getFonts();
6889
- // @ts-ignore
6890
- fonts.add(fontFace);
6891
- } catch (error) {
6892
- throw new VError$1(error, `Failed to load font ${fontName}`);
6893
- }
6894
- };
6895
-
6896
- const load = async (fontName, fontUrl) => {
6897
- return loadFont(fontName, fontUrl);
6898
- };
6899
- const ensure = async (fontName, fontUrl) => {
6900
- if (isLoaded(fontName)) {
6901
- return;
6902
- }
6903
- if (hasPending(fontName)) {
6904
- return getPending(fontName);
6905
- }
6906
- const promise = load(fontName, fontUrl);
6907
- setPending(fontName, promise);
6908
- await promise;
6909
- removePending(fontName);
6910
- setLoaded(fontName);
6911
- };
6912
-
6913
- const getSelections = editorUid => {
6914
- const editor = getEditor(editorUid);
6915
- const {
6916
- selections
6917
- } = editor;
6918
- return selections;
6919
- };
6920
-
6921
- const executeHoverProvider = (editor, offset) => {
6922
- object(editor);
6923
- number$1(offset);
6924
- return execute({
6925
- event: OnHover,
6926
- editor,
6927
- method: HoverExecute,
6928
- args: [offset],
6929
- noProviderFoundMessage: 'No hover provider found'
6930
- });
6931
- };
6932
-
6933
- const getHover = async (editor, offset) => {
6934
- object(editor);
6935
- number$1(offset);
6936
- // TODO invoke extension host worker directly
6937
- const hover = await executeHoverProvider(editor, offset);
6938
- return hover;
6939
- };
6940
-
6941
- let _ipc;
6942
- const listen$5 = async () => {
6943
- const ipc = await create$1({
6944
- method: RendererProcess
6945
- });
6946
- handleIpc(ipc);
6947
- _ipc = ipc;
6948
- };
6949
- const invoke = async (method, ...args) => {
6950
- return invoke$5(_ipc, method, ...args);
6951
- };
6952
-
6953
- const measureTextBlockHeight = (text, fontFamily, fontSize, lineHeight, width) => {
6954
- return invoke('MeasureTextBlockHeight.measureTextBlockHeight', text, fontSize, fontFamily, lineHeight, width);
6955
- };
6956
-
6957
- const deepCopy = value => {
6958
- return structuredClone(value);
6959
- };
6960
-
6961
- const getInitialLineState = initialLineState => {
6962
- return deepCopy(initialLineState);
6963
- };
6964
-
6965
- const getLineInfo$1 = (line, tokens, TokenMap) => {
6966
- const tokensLength = tokens.length;
6967
- let end = 0;
6968
- let start = 0;
6969
- const lineInfo = [];
6970
- for (let i = 0; i < tokensLength; i += 2) {
6971
- const tokenType = tokens[i];
6972
- const tokenLength = tokens[i + 1];
6973
- end += tokenLength;
6974
- const text = line.slice(start, end);
6975
- const className = `Token ${TokenMap[tokenType] || 'Unknown'}`;
6976
- const normalizedText = text;
6977
- lineInfo.push(normalizedText, className);
6978
- start = end;
6979
- }
6980
- return lineInfo;
6981
- };
6982
-
6983
- const state = {
6984
- warned: []
6985
- };
6986
- const flattenTokensArray = tokens => {
6987
- const flattened = [];
6988
- for (const token of tokens) {
6989
- object(token);
6990
- flattened.push(token.type, token.length);
6991
- }
6992
- return flattened;
7444
+ return loaded[id];
6993
7445
  };
6994
- const warnDeprecatedArrayReturn = (languageId, fn) => {
6995
- if (state.warned.includes(fn)) {
6996
- return;
6997
- }
6998
- state.warned.push(fn);
6999
- console.warn(`tokenizers without hasArrayReturn=false are deprecated (language ${languageId})`);
7446
+
7447
+ const getFonts = () => {
7448
+ // @ts-ignore
7449
+ return globalThis.fonts || document.fonts;
7000
7450
  };
7001
- const safeTokenizeLine = (languageId, tokenizeLine, line, lineStateAtStart, hasArrayReturn) => {
7451
+
7452
+ const loadFont = async (fontName, fontUrl) => {
7002
7453
  try {
7003
- const lineState = tokenizeLine(line, lineStateAtStart);
7004
- if (!lineState || !lineState.tokens || !lineState.state) {
7005
- throw new Error('invalid tokenization result');
7006
- }
7007
- if (!hasArrayReturn) {
7008
- warnDeprecatedArrayReturn(languageId, tokenizeLine);
7009
- // workaround for old tokenizers
7010
- lineState.tokens = flattenTokensArray(lineState.tokens);
7454
+ string(fontName);
7455
+ string(fontUrl);
7456
+ if (fontName.startsWith("'")) {
7457
+ throw new Error('font name is not allowed start with quotes');
7011
7458
  }
7012
- return lineState;
7459
+ const fontFace = new FontFace(fontName, fontUrl, {});
7460
+ await fontFace.load();
7461
+ const fonts = getFonts();
7462
+ // @ts-ignore
7463
+ fonts.add(fontFace);
7013
7464
  } catch (error) {
7014
- console.error(error);
7015
- return {
7016
- tokens: [/* type */0, /* length */line.length],
7017
- lineState: lineStateAtStart
7018
- };
7019
- }
7020
- };
7021
-
7022
- const getLineInfos = (lines, tokenizer, languageId) => {
7023
- const lineInfos = [];
7024
- const {
7025
- tokenizeLine,
7026
- initialLineState,
7027
- hasArrayReturn,
7028
- TokenMap
7029
- } = tokenizer;
7030
- let currentLineState = getInitialLineState(initialLineState);
7031
- for (const line of lines) {
7032
- const result = safeTokenizeLine(languageId, tokenizeLine, line, currentLineState, hasArrayReturn);
7033
- const {
7034
- tokens
7035
- } = result;
7036
- const lineInfo = getLineInfo$1(line, tokens, TokenMap);
7037
- lineInfos.push(lineInfo);
7038
- currentLineState = result;
7465
+ throw new VError$1(error, `Failed to load font ${fontName}`);
7039
7466
  }
7040
- return lineInfos;
7041
7467
  };
7042
7468
 
7043
- const tokenizeCodeBlock = async (codeBlock, languageId, tokenizerPath) => {
7044
- await loadTokenizer(languageId, tokenizerPath);
7045
- const tokenizer = getTokenizer(languageId);
7046
- const lines = splitLines$2(codeBlock);
7047
- const lineInfos = getLineInfos(lines, tokenizer, languageId);
7048
- return lineInfos;
7469
+ const load = async (fontName, fontUrl) => {
7470
+ return loadFont(fontName, fontUrl);
7049
7471
  };
7050
-
7051
- const getHoverPosition = (position, selections) => {
7052
- if (position) {
7053
- return position;
7472
+ const ensure = async (fontName, fontUrl) => {
7473
+ if (isLoaded(fontName)) {
7474
+ return;
7054
7475
  }
7055
- const rowIndex = selections[0];
7056
- const columnIndex = selections[1];
7057
- return {
7058
- rowIndex,
7059
- columnIndex
7060
- };
7061
- };
7062
- const getMatchingDiagnostics = (diagnostics, rowIndex, columnIndex) => {
7063
- const matching = [];
7064
- for (const diagnostic of diagnostics) {
7065
- if (diagnostic.rowIndex === rowIndex) {
7066
- matching.push(diagnostic);
7067
- }
7476
+ if (hasPending(fontName)) {
7477
+ return getPending(fontName);
7068
7478
  }
7069
- return matching;
7479
+ const promise = load(fontName, fontUrl);
7480
+ setPending(fontName, promise);
7481
+ await promise;
7482
+ removePending(fontName);
7483
+ setLoaded(fontName);
7070
7484
  };
7071
- const fallbackDisplayStringLanguageId = 'typescript'; // TODO remove this
7072
7485
 
7073
- const hoverDocumentationFontSize = 15;
7074
- const hoverDocumentationFontFamily = 'Fira Code';
7075
- const hoverDocumentationLineHeight = '1.33333';
7076
- const hoverBorderLeft = 1;
7077
- const hoverBorderRight = 1;
7078
- const hoverPaddingLeft = 8;
7079
- const hoverPaddingRight = 8;
7080
- const hovverFullWidth = 400;
7081
- const hoverDocumentationWidth = hovverFullWidth - hoverPaddingLeft - hoverPaddingRight - hoverBorderLeft - hoverBorderRight;
7082
- const getHoverPositionXy = (editor, rowIndex, wordStart, documentationHeight) => {
7083
- const x$1 = x(editor, rowIndex, wordStart);
7084
- const y$1 = editor.height - y(editor, rowIndex) + editor.y + 40;
7085
- return {
7086
- x: x$1,
7087
- y: y$1
7088
- };
7089
- };
7090
- const getEditorHoverInfo = async (editorUid, position) => {
7091
- number$1(editorUid);
7092
- const instance = get$6(editorUid);
7093
- const editor = instance.newState;
7486
+ const getSelections = editorUid => {
7487
+ const editor = getEditor(editorUid);
7094
7488
  const {
7095
7489
  selections
7096
7490
  } = editor;
7491
+ return selections;
7492
+ };
7493
+
7494
+ const getText = editorUid => {
7495
+ const editor = getEditor(editorUid);
7097
7496
  const {
7098
- rowIndex,
7099
- columnIndex
7100
- } = getHoverPosition(position, selections);
7101
- const offset = offsetAt(editor, rowIndex, columnIndex);
7102
- const hover = await getHover(editor, offset);
7103
- if (!hover) {
7104
- return undefined;
7105
- }
7106
- const {
7107
- displayString,
7108
- documentation,
7109
- displayStringLanguageId
7110
- } = hover;
7111
- const tokenizerPath = '';
7112
- const lineInfos = await tokenizeCodeBlock(displayString, displayStringLanguageId || fallbackDisplayStringLanguageId, tokenizerPath);
7113
- const wordPart = await getWordBefore(editor, rowIndex, columnIndex);
7114
- const wordStart = columnIndex - wordPart.length;
7115
- await measureTextBlockHeight(documentation, hoverDocumentationFontFamily, hoverDocumentationFontSize, hoverDocumentationLineHeight, hoverDocumentationWidth);
7116
- const {
7117
- x,
7118
- y
7119
- } = getHoverPositionXy(editor, rowIndex, wordStart);
7120
- const diagnostics = editor.diagnostics || [];
7121
- const matchingDiagnostics = getMatchingDiagnostics(diagnostics, rowIndex);
7122
- return {
7123
- lineInfos,
7124
- documentation,
7125
- x,
7126
- y,
7127
- matchingDiagnostics
7128
- };
7497
+ lines
7498
+ } = editor;
7499
+ return lines.join('\n');
7129
7500
  };
7130
7501
 
7131
7502
  const InsertText = 'insertText';
@@ -7694,37 +8065,6 @@ const getVisible = async (editor, syncIncremental) => {
7694
8065
  };
7695
8066
  };
7696
8067
 
7697
- const Div = 4;
7698
- const Span = 8;
7699
- const Text = 12;
7700
- const Img = 17;
7701
-
7702
- const ColoredMaskIcon = 'ColoredMaskIcon';
7703
- const ColorPicker = 'ColorPicker';
7704
- const ColorPickerBackgroundColor = 'ColorPickerBackgroundColor';
7705
- const ColorPickerDark = 'ColorPickerDark';
7706
- const ColorPickerLight = 'ColorPickerLight';
7707
- const ColorPickerRectangle = 'ColorPickerRectangle';
7708
- const ColorPickerSlider = 'ColorPickerSlider';
7709
- const ColorPickerSliderThumb = 'ColorPickerSliderThumb';
7710
- const Diagnostic = 'Diagnostic';
7711
- const EditorCompletionItem = 'EditorCompletionItem';
7712
- const EditorCompletionItemDeprecated = 'EditorCompletionItemDeprecated';
7713
- const EditorCompletionItemFocused = 'EditorCompletionItemFocused';
7714
- const EditorCompletionItemHighlight = 'EditorCompletionItemHighlight';
7715
- const EditorCursor = 'EditorCursor';
7716
- const EditorRow = 'EditorRow';
7717
- const EditorSelection = 'EditorSelection';
7718
- const FileIcon = 'FileIcon';
7719
- const HoverDisplayString = 'HoverDisplayString';
7720
- const HoverDocumentation = 'HoverDocumentation';
7721
- const HoverEditorRow = 'HoverEditorRow';
7722
- const HoverProblem = 'HoverProblem';
7723
- const HoverProblemDetail = 'HoverProblemDetail';
7724
- const HoverProblemMessage = 'HoverProblemMessage';
7725
- const Label = 'Label';
7726
- const Viewlet = 'Viewlet';
7727
-
7728
8068
  const getCursorsVirtualDom = cursors => {
7729
8069
  const dom = [];
7730
8070
  for (const translate of cursors) {
@@ -7776,14 +8116,6 @@ const getDiagnosticsVirtualDom = diagnostics => {
7776
8116
  return dom;
7777
8117
  };
7778
8118
 
7779
- const text = data => {
7780
- return {
7781
- type: Text,
7782
- text: data,
7783
- childCount: 0
7784
- };
7785
- };
7786
-
7787
8119
  const getGutterInfoVirtualDom = gutterInfo => {
7788
8120
  return [{
7789
8121
  type: Span,
@@ -8052,13 +8384,6 @@ const getVisibleItems = (filteredItems, itemHeight, leadingWord, minLineY, maxLi
8052
8384
  return visibleItems;
8053
8385
  };
8054
8386
 
8055
- const SetBounds = 'setBounds';
8056
- const SetColor = 'setColor';
8057
- const SetContentHeight = 'setContentHeight';
8058
- const SetNegativeMargin = 'setNegativeMargin';
8059
- const SetOffsetX = 'setOffsetX';
8060
- const SetScrollBar = 'setScrollBar';
8061
-
8062
8387
  const renderItems = {
8063
8388
  isEqual(oldState, newState) {
8064
8389
  return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.focusedIndex === newState.focusedIndex;
@@ -8069,7 +8394,7 @@ const renderItems = {
8069
8394
  return ['setDom', dom];
8070
8395
  }
8071
8396
  };
8072
- const renderBounds$1 = {
8397
+ const renderBounds = {
8073
8398
  isEqual(oldState, newState) {
8074
8399
  return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.x === newState.x && oldState.y === newState.y;
8075
8400
  },
@@ -8115,10 +8440,10 @@ const renderScrollBar = {
8115
8440
  return [/* method */SetScrollBar, /* scrollBarY */scrollBarY, /* scrollBarHeight */scrollBarHeight];
8116
8441
  }
8117
8442
  };
8118
- const render$3 = [renderItems, renderBounds$1, renderHeight, renderNegativeMargin, renderScrollBar];
8443
+ const render$1 = [renderItems, renderBounds, renderHeight, renderNegativeMargin, renderScrollBar];
8119
8444
  const renderCompletion$1 = (oldState, newState) => {
8120
8445
  const commands = [];
8121
- for (const item of render$3) {
8446
+ for (const item of render$1) {
8122
8447
  if (!item.isEqual(oldState, newState)) {
8123
8448
  commands.push(item.apply(oldState, newState));
8124
8449
  }
@@ -8128,7 +8453,12 @@ const renderCompletion$1 = (oldState, newState) => {
8128
8453
 
8129
8454
  const renderCompletion = (oldState, newState) => {
8130
8455
  const commands = renderCompletion$1(oldState, newState);
8131
- return commands;
8456
+ const wrappedCommands = [];
8457
+ const uid = newState.uid;
8458
+ for (const command of commands) {
8459
+ wrappedCommands.push(['Viewlet.send', uid, ...command]);
8460
+ }
8461
+ return wrappedCommands;
8132
8462
  };
8133
8463
  const addWidgetCompletion = widget => {
8134
8464
  const commands = renderCompletion(widget.oldState, widget.newState);
@@ -8138,9 +8468,7 @@ const addWidgetCompletion = widget => {
8138
8468
  const uid = widget.newState.uid;
8139
8469
  const allCommands = [];
8140
8470
  allCommands.push(['Viewlet.create', id, uid]);
8141
- for (const command of commands) {
8142
- allCommands.push(['Viewlet.send', uid, ...command]);
8143
- }
8471
+ allCommands.push(...commands);
8144
8472
  return allCommands;
8145
8473
  };
8146
8474
  const addWidget = widget => {
@@ -8154,6 +8482,17 @@ const addWidget = widget => {
8154
8482
  throw new Error('unsupported widget');
8155
8483
  }
8156
8484
  };
8485
+ const renderWidget = widget => {
8486
+ const {
8487
+ id
8488
+ } = widget;
8489
+ switch (id) {
8490
+ case 'completion':
8491
+ return renderCompletion(widget.oldState, widget.newState);
8492
+ default:
8493
+ throw new Error(`unsupported widget`);
8494
+ }
8495
+ };
8157
8496
  const removeCompletion = widget => {
8158
8497
  return [['Viewlet.send', widget.newState.uid, 'dispose']];
8159
8498
  };
@@ -8271,6 +8610,7 @@ const renderWidgets = {
8271
8610
  },
8272
8611
  apply(oldState, newState) {
8273
8612
  const addedWidgets = [];
8613
+ const changedWidgets = [];
8274
8614
  const removedWidgets = [];
8275
8615
  const oldWidgets = oldState.widgets || [];
8276
8616
  const newWidgets = newState.widgets || [];
@@ -8283,7 +8623,9 @@ const renderWidgets = {
8283
8623
  newWidgetMap[newWidget.id] = newWidget;
8284
8624
  }
8285
8625
  for (const oldWidget of oldWidgets) {
8286
- if (oldWidget.id in newWidgetMap) ; else {
8626
+ if (oldWidget.id in newWidgetMap) {
8627
+ changedWidgets.push(newWidgetMap[oldWidget.id]);
8628
+ } else {
8287
8629
  removedWidgets.push(oldWidget);
8288
8630
  }
8289
8631
  }
@@ -8299,6 +8641,13 @@ const renderWidgets = {
8299
8641
  addCommands.push(...childCommands);
8300
8642
  }
8301
8643
  }
8644
+ const changeCommands = [];
8645
+ for (const changedWidget of changedWidgets) {
8646
+ const childCommands = renderWidget(changedWidget);
8647
+ if (childCommands.length > 0) {
8648
+ changeCommands.push(...childCommands);
8649
+ }
8650
+ }
8302
8651
  const removeCommands = [];
8303
8652
  for (const removedWidget of removedWidgets) {
8304
8653
  const childCommands = removeWidget(removedWidget);
@@ -8306,12 +8655,12 @@ const renderWidgets = {
8306
8655
  removeCommands.push(...childCommands);
8307
8656
  }
8308
8657
  }
8309
- const allCommands = [...addCommands, ...removeCommands];
8658
+ const allCommands = [...addCommands, ...changeCommands, ...removeCommands];
8310
8659
  return allCommands;
8311
8660
  },
8312
8661
  multiple: true
8313
8662
  };
8314
- const render$2 = [renderLines, renderSelections, renderScrollBarX, renderScrollBarY, renderFocus, renderDecorations, renderGutterInfo, renderWidgets];
8663
+ const render = [renderLines, renderSelections, renderScrollBarX, renderScrollBarY, renderFocus, renderDecorations, renderGutterInfo, renderWidgets];
8315
8664
  const renderEditor = async id => {
8316
8665
  const instance = get$6(id);
8317
8666
  if (!instance) {
@@ -8323,7 +8672,7 @@ const renderEditor = async id => {
8323
8672
  } = instance;
8324
8673
  const commands = [];
8325
8674
  set$6(id, newState, newState);
8326
- for (const item of render$2) {
8675
+ for (const item of render) {
8327
8676
  if (!item.isEqual(oldState, newState)) {
8328
8677
  const result = await item.apply(oldState, newState);
8329
8678
  // @ts-ignore
@@ -8331,59 +8680,10 @@ const renderEditor = async id => {
8331
8680
  commands.push(...result);
8332
8681
  } else if (result.length > 0) {
8333
8682
  commands.push(result);
8334
- }
8335
- }
8336
- }
8337
- return commands;
8338
- };
8339
-
8340
- const openCompletion = async editor => {
8341
- const {
8342
- widgets,
8343
- uid
8344
- } = editor;
8345
- const completionUid = Math.random();
8346
- const completionWidget = {
8347
- id: 'completion',
8348
- oldState: {
8349
- items: [],
8350
- itemHeight: 20,
8351
- maxHeight: 150,
8352
- minLineY: 0,
8353
- maxLineY: 0,
8354
- uid: completionUid
8355
- },
8356
- newState: {
8357
- items: [],
8358
- itemHeight: 20,
8359
- maxHeight: 150,
8360
- minLineY: 0,
8361
- maxLineY: 10,
8362
- uid: completionUid
8683
+ }
8363
8684
  }
8364
- };
8365
- const newWidgets = [...widgets, completionWidget];
8366
- const newEditor = {
8367
- ...editor,
8368
- widgets: newWidgets
8369
- };
8370
- set$6(uid, editor, newEditor);
8371
- const newCompletionWidget = await loadContent$2(uid, completionWidget.newState);
8372
- const FocusEditorCompletions = 9;
8373
- await invoke$3('Focus.setAdditionalFocus', FocusEditorCompletions);
8374
- const latestEditor = getEditor(uid);
8375
- if (!latestEditor.widgets.includes(completionWidget)) {
8376
- return editor;
8377
8685
  }
8378
- const index = latestEditor.widgets.indexOf(completionWidget);
8379
- const latestWidgets = [...latestEditor.widgets.slice(0, index), {
8380
- ...completionWidget,
8381
- newState: newCompletionWidget
8382
- }, ...latestEditor.widgets.slice(index + 1)];
8383
- return {
8384
- ...latestEditor,
8385
- widgets: latestWidgets
8386
- };
8686
+ return commands;
8387
8687
  };
8388
8688
 
8389
8689
  const keep = ['ColorPicker.handleSliderPointerDown', 'ColorPicker.handleSliderPointerMove', 'ColorPicker.loadContent', 'Editor.create', 'Editor.getWordAt', 'Editor.getWordBefore', 'Editor.offsetAt', 'Editor.render', 'ColorPicker.render', 'Editor.getText', 'Editor.getSelections',
@@ -8417,239 +8717,6 @@ const wrapCommands = commands => {
8417
8717
  }
8418
8718
  };
8419
8719
 
8420
- const HandlePointerDown = 'handlePointerDown';
8421
- const HandleSashPointerDown = 'handleSashPointerDown';
8422
-
8423
- const mergeClassNames = (...classNames) => {
8424
- return classNames.filter(Boolean).join(' ');
8425
- };
8426
-
8427
- const getColorPickerVirtualDom = () => {
8428
- return [{
8429
- type: Div,
8430
- className: mergeClassNames(Viewlet, ColorPicker),
8431
- onPointerDown: HandlePointerDown,
8432
- childCount: 3
8433
- }, {
8434
- type: Div,
8435
- className: ColorPickerRectangle,
8436
- childCount: 3
8437
- }, {
8438
- type: Div,
8439
- className: ColorPickerBackgroundColor,
8440
- childCount: 0
8441
- }, {
8442
- type: Div,
8443
- className: ColorPickerLight,
8444
- childCount: 0
8445
- }, {
8446
- type: Div,
8447
- className: ColorPickerDark,
8448
- childCount: 0
8449
- }, {
8450
- type: Div,
8451
- className: ColorPickerSlider,
8452
- childCount: 0
8453
- }, {
8454
- type: Div,
8455
- className: ColorPickerSliderThumb,
8456
- childCount: 0
8457
- }];
8458
- };
8459
-
8460
- const renderColor = {
8461
- isEqual(oldState, newState) {
8462
- return oldState.color === newState.color;
8463
- },
8464
- apply(oldState, newState) {
8465
- return [/* method */SetColor, /* color */newState.color];
8466
- }
8467
- };
8468
- const renderOffsetX = {
8469
- isEqual(oldState, newState) {
8470
- return oldState.offsetX === newState.offsetX;
8471
- },
8472
- apply(oldState, newState) {
8473
- return [/* method */SetOffsetX, /* offsetX */newState.offsetX];
8474
- }
8475
- };
8476
- const renderColorPickerDom = {
8477
- isEqual(oldState, newState) {
8478
- return oldState.min === newState.min && oldState.max === newState.max;
8479
- },
8480
- apply(oldState, newState) {
8481
- const dom = getColorPickerVirtualDom();
8482
- return ['Viewlet.setDom2', dom];
8483
- }
8484
- };
8485
- const render$1 = [renderColorPickerDom, renderColor, renderOffsetX];
8486
- const renderColorPicker = async (oldState, newState) => {
8487
- const commands = [];
8488
- for (const item of render$1) {
8489
- if (!item.isEqual(oldState, newState)) {
8490
- commands.push(item.apply(oldState, newState));
8491
- }
8492
- }
8493
- return commands;
8494
- };
8495
-
8496
- const loadContent = async (editorUid, state, position) => {
8497
- const hoverInfo = await getEditorHoverInfo(editorUid, position);
8498
- if (!hoverInfo) {
8499
- return state;
8500
- }
8501
- const {
8502
- lineInfos,
8503
- documentation,
8504
- x,
8505
- y,
8506
- matchingDiagnostics
8507
- } = hoverInfo;
8508
- return {
8509
- ...state,
8510
- lineInfos,
8511
- documentation,
8512
- x,
8513
- y,
8514
- diagnostics: matchingDiagnostics
8515
- };
8516
- };
8517
- const handleSashPointerDown = (state, eventX, eventY) => {
8518
- return state;
8519
- };
8520
- const handleSashPointerMove = (state, eventX, eventY) => {
8521
- // @ts-ignore
8522
- const {
8523
- x,
8524
- y
8525
- } = state;
8526
- const minWidth = 100;
8527
- const newWidth = Math.max(eventX - x, minWidth);
8528
- return {
8529
- ...state,
8530
- resizedWidth: newWidth
8531
- };
8532
- };
8533
- const handleSashPointerUp = (state, eventX, eventY) => {
8534
- return state;
8535
- };
8536
-
8537
- const getLineInfoVirtualDom = lineInfo => {
8538
- const dom = [{
8539
- type: Div,
8540
- className: HoverEditorRow,
8541
- childCount: lineInfo.length / 2
8542
- }];
8543
- for (let i = 0; i < lineInfo.length; i += 2) {
8544
- const tokenText = lineInfo[i];
8545
- const tokenClass = lineInfo[i + 1];
8546
- dom.push({
8547
- type: Span,
8548
- className: tokenClass,
8549
- childCount: 1
8550
- },
8551
- // @ts-ignore
8552
- text(tokenText));
8553
- }
8554
- return dom;
8555
- };
8556
- const getLineInfosVirtualDom = lineInfos => {
8557
- const dom = lineInfos.flatMap(getLineInfoVirtualDom);
8558
- return dom;
8559
- };
8560
-
8561
- const hoverProblemMessage = {
8562
- type: Span,
8563
- className: HoverProblemMessage,
8564
- childCount: 1
8565
- };
8566
- const hoverProblemDetail = {
8567
- type: Span,
8568
- className: HoverProblemDetail,
8569
- childCount: 1
8570
- };
8571
- const getChildCount = (lineInfos, documentation, diagnostics) => {
8572
- return lineInfos.length + documentation ? 1 : 0 + (diagnostics && diagnostics.length > 0) ? 1 : 0;
8573
- };
8574
- const getHoverVirtualDom = (lineInfos, documentation, diagnostics) => {
8575
- const dom = [];
8576
- dom.push({
8577
- type: Div,
8578
- className: 'Viewlet EditorHover',
8579
- childCount: getChildCount(lineInfos, documentation, diagnostics) + 1
8580
- });
8581
- if (diagnostics && diagnostics.length > 0) {
8582
- dom.push({
8583
- type: Div,
8584
- className: `${HoverDisplayString} ${HoverProblem}`,
8585
- childCount: diagnostics.length * 2
8586
- });
8587
- for (const diagnostic of diagnostics) {
8588
- dom.push(hoverProblemMessage, text(diagnostic.message), hoverProblemDetail, text(`${diagnostic.source} (${diagnostic.code})`));
8589
- }
8590
- }
8591
- if (lineInfos.length > 0) {
8592
- const lineInfosDom = getLineInfosVirtualDom(lineInfos);
8593
- dom.push({
8594
- type: Div,
8595
- className: HoverDisplayString,
8596
- childCount: lineInfos.length
8597
- }, ...lineInfosDom);
8598
- }
8599
- if (documentation) {
8600
- dom.push({
8601
- type: Div,
8602
- className: HoverDocumentation,
8603
- childCount: 1
8604
- }, text(documentation));
8605
- }
8606
- dom.push({
8607
- type: Div,
8608
- className: 'Sash SashVertical SashResize',
8609
- childCount: 0,
8610
- onPointerDown: HandleSashPointerDown
8611
- });
8612
- return dom;
8613
- };
8614
-
8615
- const renderHoverDom = {
8616
- isEqual(oldState, newState) {
8617
- return oldState.lineInfos === newState.lineInfos && oldState.documentation === newState.documentation && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.diagnostics === newState.diagnostics;
8618
- },
8619
- apply(oldState, newState) {
8620
- const dom = getHoverVirtualDom(newState.lineInfos, newState.documentation, newState.diagnostics);
8621
- return [/* method */'Viewlet.setDom2', dom];
8622
- }
8623
- };
8624
- const renderBounds = {
8625
- isEqual(oldState, newState) {
8626
- return oldState.x === newState.x && oldState.y === newState.y && oldState.resizedWidth === newState.resizedWidth;
8627
- },
8628
- apply(oldState, newState) {
8629
- // @ts-ignore
8630
- const {
8631
- x,
8632
- y,
8633
- width,
8634
- height,
8635
- resizedWidth,
8636
- uid
8637
- } = newState;
8638
- console.log('apply');
8639
- return [SetBounds, x, y, resizedWidth, height];
8640
- }
8641
- };
8642
- const render = [renderHoverDom, renderBounds];
8643
- const renderHover = async (oldState, newState) => {
8644
- const commands = [];
8645
- for (const item of render) {
8646
- if (!item.isEqual(oldState, newState)) {
8647
- commands.push(item.apply(oldState, newState));
8648
- }
8649
- }
8650
- return commands;
8651
- };
8652
-
8653
8720
  const commandMap = {
8654
8721
  'ColorPicker.handleSliderPointerDown': handleSliderPointerDown,
8655
8722
  'ColorPicker.handleSliderPointerMove': handleSliderPointerMove,
@@ -8696,6 +8763,7 @@ const commandMap = {
8696
8763
  'Editor.deleteWordRight': deleteWordRight,
8697
8764
  'Editor.findAllReferences': findAllReferences,
8698
8765
  'Editor.format': format,
8766
+ 'Editor.getSelections': getSelections,
8699
8767
  'Editor.getText': getText,
8700
8768
  'Editor.getWordAt': getWordAt,
8701
8769
  'Editor.getWordBefore': getWordBefore,
@@ -8775,8 +8843,11 @@ const commandMap = {
8775
8843
  'Editor.typeWithAutoClosing': typeWithAutoClosing,
8776
8844
  'Editor.undo': undo,
8777
8845
  'Editor.unIndent': editorUnindent,
8778
- 'Editor.getSelections': getSelections,
8779
8846
  'EditorCompletion.advance': advance,
8847
+ 'EditorCompletion.focusFirst': focusFirst$1,
8848
+ 'EditorCompletion.focusIndex': focusIndex$1,
8849
+ 'EditorCompletion.focusNext': focusNext$1,
8850
+ 'EditorCompletion.focusPrevious': focusPrevious$1,
8780
8851
  'EditorCompletion.handleEditorBlur': handleEditorBlur,
8781
8852
  'EditorCompletion.handleEditorClick': handleEditorClick,
8782
8853
  'EditorCompletion.handleEditorDeleteLeft': handleEditorDeleteLeft,
@@ -8790,14 +8861,14 @@ const commandMap = {
8790
8861
  'FindWidget.focusNext': focusNext,
8791
8862
  'FindWidget.focusPrevious': focusPrevious,
8792
8863
  'FindWidget.handleInput': handleInput,
8793
- 'FindWidget.loadContent': loadContent$1,
8864
+ 'FindWidget.loadContent': loadContent,
8794
8865
  'Font.ensure': ensure,
8795
8866
  'Hover.getHoverInfo': getEditorHoverInfo,
8796
8867
  'Hover.handleSashPointerDown': handleSashPointerDown,
8797
8868
  'Hover.handleSashPointerMove': handleSashPointerMove,
8798
8869
  'Hover.handleSashPointerUp': handleSashPointerUp,
8870
+ 'Hover.loadContent': loadContent$1,
8799
8871
  'Hover.render': renderHover,
8800
- 'Hover.loadContent': loadContent,
8801
8872
  'Initialize.initialize': intialize
8802
8873
  };
8803
8874
  wrapCommands(commandMap);