@lvce-editor/editor-worker 19.29.11 → 19.29.13

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.
@@ -1397,8 +1397,10 @@ const KeyJ = 38;
1397
1397
  const KeyK = 39;
1398
1398
  const KeyL = 40;
1399
1399
  const KeyO = 43;
1400
+ const KeyU = 49;
1400
1401
  const KeyV = 50;
1401
1402
  const KeyX = 52;
1403
+ const KeyY = 53;
1402
1404
  const KeyZ = 54;
1403
1405
  const F2 = 58;
1404
1406
  const F3 = 59;
@@ -4209,15 +4211,24 @@ const scheduleDocumentAndCursorsSelections = async (editor, changes, selectionCh
4209
4211
  // then clear old undostack from indexeddb after 3 days
4210
4212
  // TODO should push to undostack after rendering
4211
4213
  const autoClosingRanges = applyAutoClosingRangesEdit(editor, changes);
4214
+ const change = changes[0];
4215
+ const canCoalesceTyping = changes.length === 1 && change.origin === EditorType && change.deleted[0] === '' && change.inserted[0].length > 0 && change.inserted.length === 1 && change.start.rowIndex === change.end.rowIndex && change.start.columnIndex === change.end.columnIndex;
4216
+ const previous = editor.undoStack.at(-1)?.[0];
4217
+ const shouldCoalesce = editor.canCoalesceTyping && canCoalesceTyping && change.start.rowIndex === previous.start.rowIndex && change.start.columnIndex === previous.start.columnIndex + previous.inserted[0].length;
4218
+ const undoStack = shouldCoalesce ? [...editor.undoStack.slice(0, -1), [{
4219
+ ...previous,
4220
+ inserted: [previous.inserted[0] + change.inserted[0]]
4221
+ }]] : [...editor.undoStack, changes];
4212
4222
  const newEditor = {
4213
4223
  ...partialNewEditor,
4214
4224
  autoClosingRanges,
4225
+ canCoalesceTyping,
4215
4226
  invalidStartIndex,
4216
4227
  lines: newLines,
4217
4228
  modified: true,
4218
4229
  redoStack: [],
4219
4230
  selections: newSelections,
4220
- undoStack: [...editor.undoStack, changes]
4231
+ undoStack
4221
4232
  };
4222
4233
  // Update link decorations after text changes
4223
4234
  const linkDecorations = detectAllLinksAsDecorations(newEditor);
@@ -5642,18 +5653,6 @@ const getCursorOffset = editor => {
5642
5653
  return offsetAt(editor, editor.selections[0], editor.selections[1]);
5643
5654
  };
5644
5655
 
5645
- const cancelSelection = editor => {
5646
- const {
5647
- selections
5648
- } = editor;
5649
- if (selections.length === 4 && selections[0] === selections[2] && selections[1] === selections[3]) {
5650
- return editor;
5651
- }
5652
- const newSelections = alloc(4);
5653
- moveRangeToPosition$1(newSelections, 0, selections[0], selections[1]);
5654
- return scheduleSelections(editor, newSelections);
5655
- };
5656
-
5657
5656
  const getIndex = (widgets, id) => {
5658
5657
  for (const [i, widget] of widgets.entries()) {
5659
5658
  if (widget.id === id) {
@@ -5668,6 +5667,28 @@ const removeEditorWidget = (widgets, id) => {
5668
5667
  return newWidgets;
5669
5668
  };
5670
5669
 
5670
+ const cancelSelection = editor => {
5671
+ const {
5672
+ selections,
5673
+ widgets = []
5674
+ } = editor;
5675
+ if (widgets.some(widget => widget.id === Hover)) {
5676
+ return {
5677
+ ...editor,
5678
+ additionalFocus: 0,
5679
+ focused: true,
5680
+ widgetRevision: next(editor.uid),
5681
+ widgets: removeEditorWidget(widgets, Hover)
5682
+ };
5683
+ }
5684
+ if (selections.length === 4 && selections[0] === selections[2] && selections[1] === selections[3]) {
5685
+ return editor;
5686
+ }
5687
+ const newSelections = alloc(4);
5688
+ moveRangeToPosition$1(newSelections, 0, selections[0], selections[1]);
5689
+ return scheduleSelections(editor, newSelections);
5690
+ };
5691
+
5671
5692
  const isMatchingWidget$2 = widget => {
5672
5693
  return widget.id === CodeGenerator;
5673
5694
  };
@@ -6396,6 +6417,21 @@ const cursorSet = (editor, rowIndex, columnIndex) => {
6396
6417
  return scheduleSelections(editor, selectionEdits);
6397
6418
  };
6398
6419
 
6420
+ const cursorUndo$1 = editor => {
6421
+ const {
6422
+ cursorUndoStack = []
6423
+ } = editor;
6424
+ if (cursorUndoStack.length === 0) {
6425
+ return editor;
6426
+ }
6427
+ const selections = cursorUndoStack.at(-1);
6428
+ const newEditor = {
6429
+ ...editor,
6430
+ cursorUndoStack: cursorUndoStack.slice(0, -1)
6431
+ };
6432
+ return scheduleSelections(newEditor, selections);
6433
+ };
6434
+
6399
6435
  const moveSelectionWithoutIntlSegmenter = (selections, i, selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) => {
6400
6436
  if (selectionStartRow === 0) {
6401
6437
  moveRangeToPosition$1(selections, i, 0, 0);
@@ -6877,6 +6913,7 @@ const i18nString = (key, placeholders = emptyObject) => {
6877
6913
  };
6878
6914
 
6879
6915
  const Copy = 'Copy';
6916
+ const CursorUndo = 'Cursor Undo';
6880
6917
  const Cut = 'Cut';
6881
6918
  const DeleteLine = 'Delete Line';
6882
6919
  const EditorCloseColorPicker = 'Editor: Close Color Picker';
@@ -6911,9 +6948,11 @@ const NoDefinitionFoundFor = "No definition found for '{PH1}'";
6911
6948
  const NoTypeDefinitionFound = 'No type definition found';
6912
6949
  const NoTypeDefinitionFoundFor = "No type definition found for '{PH1}'";
6913
6950
  const Paste = 'Paste';
6951
+ const Redo = 'Redo';
6914
6952
  const SourceAction = 'Source Action';
6915
6953
  const ToggleBlockComment = 'Toggle Block Comment';
6916
6954
  const ToggleBreakpoint = 'Toggle Breakpoint';
6955
+ const Undo = 'Undo';
6917
6956
  const Unfold = 'Editor: Unfold';
6918
6957
 
6919
6958
  const goToDefinition$1 = () => {
@@ -6968,6 +7007,15 @@ const copy = () => {
6968
7007
  const paste$1 = () => {
6969
7008
  return i18nString(Paste);
6970
7009
  };
7010
+ const cursorUndo = () => {
7011
+ return i18nString(CursorUndo);
7012
+ };
7013
+ const undo$1 = () => {
7014
+ return i18nString(Undo);
7015
+ };
7016
+ const redo$1 = () => {
7017
+ return i18nString(Redo);
7018
+ };
6971
7019
  const unfold$1 = () => {
6972
7020
  return i18nString(Unfold);
6973
7021
  };
@@ -11499,6 +11547,10 @@ const getKeyBindings = () => {
11499
11547
  command: 'Editor.closeColorPicker',
11500
11548
  key: Escape,
11501
11549
  when: FocusColorPicker
11550
+ }, {
11551
+ command: 'Editor.cancelSelection',
11552
+ key: Escape,
11553
+ when: FocusEditorHover
11502
11554
  }, {
11503
11555
  command: 'Editor.closeSourceAction',
11504
11556
  key: Escape,
@@ -11707,6 +11759,18 @@ const getKeyBindings = () => {
11707
11759
  command: 'Editor.undo',
11708
11760
  key: CtrlCmd | KeyZ,
11709
11761
  when: FocusEditorText
11762
+ }, {
11763
+ command: 'Editor.cursorUndo',
11764
+ key: CtrlCmd | KeyU,
11765
+ when: FocusEditorText
11766
+ }, {
11767
+ command: 'Editor.redo',
11768
+ key: CtrlCmd | Shift | KeyZ,
11769
+ when: FocusEditorText
11770
+ }, {
11771
+ command: 'Editor.redo',
11772
+ key: CtrlCmd | KeyY,
11773
+ when: FocusEditorText
11710
11774
  }, {
11711
11775
  command: 'Editor.cursorLeft',
11712
11776
  key: LeftArrow,
@@ -11945,6 +12009,15 @@ const getProblems = async () => {
11945
12009
 
11946
12010
  const getQuickPickMenuEntries = () => {
11947
12011
  return [{
12012
+ id: 'Editor.undo',
12013
+ label: undo$1()
12014
+ }, {
12015
+ id: 'Editor.redo',
12016
+ label: redo$1()
12017
+ }, {
12018
+ id: 'Editor.cursorUndo',
12019
+ label: cursorUndo()
12020
+ }, {
11948
12021
  id: 'Editor.fold',
11949
12022
  label: fold()
11950
12023
  }, {
@@ -12387,6 +12460,26 @@ const getErrorMessage = error => {
12387
12460
  }
12388
12461
  return String(error);
12389
12462
  };
12463
+ const getSavedHistory = (savedState, content) => {
12464
+ if (!savedState || typeof savedState !== 'object') {
12465
+ return undefined;
12466
+ }
12467
+ const {
12468
+ lines,
12469
+ redoStack,
12470
+ undoStack
12471
+ } = savedState;
12472
+ if (!Array.isArray(lines) || lines.some(line => typeof line !== 'string') || lines.join('\n') !== content) {
12473
+ return undefined;
12474
+ }
12475
+ if (!Array.isArray(redoStack) || !Array.isArray(undoStack)) {
12476
+ return undefined;
12477
+ }
12478
+ return {
12479
+ redoStack,
12480
+ undoStack
12481
+ };
12482
+ };
12390
12483
  const loadContent = async (state, savedState) => {
12391
12484
  const {
12392
12485
  assetDir,
@@ -12470,6 +12563,7 @@ const loadContent = async (state, savedState) => {
12470
12563
  textInfos: []
12471
12564
  };
12472
12565
  }
12566
+ const savedHistory = existingEditor ? undefined : getSavedHistory(savedState, content);
12473
12567
 
12474
12568
  // TODO avoid creating intermediate editors here
12475
12569
  const newEditor1 = setBounds(newEditor0, x, y, width, height, 9);
@@ -12501,8 +12595,8 @@ const loadContent = async (state, savedState) => {
12501
12595
  completionsOnType,
12502
12596
  initial: false,
12503
12597
  modified: existingEditor?.modified || false,
12504
- redoStack: existingEditor?.redoStack || [],
12505
- undoStack: existingEditor?.undoStack || []
12598
+ redoStack: existingEditor?.redoStack || savedHistory?.redoStack || [],
12599
+ undoStack: existingEditor?.undoStack || savedHistory?.undoStack || []
12506
12600
  };
12507
12601
  return newEditor5;
12508
12602
  };
@@ -13513,10 +13607,14 @@ const renderEventListeners = () => {
13513
13607
 
13514
13608
  const saveState = (state, savedState) => {
13515
13609
  const {
13516
- lines
13610
+ lines,
13611
+ redoStack,
13612
+ undoStack
13517
13613
  } = state;
13518
13614
  return {
13519
- lines
13615
+ lines,
13616
+ redoStack,
13617
+ undoStack
13520
13618
  };
13521
13619
  };
13522
13620
 
@@ -13734,6 +13832,21 @@ const editorDiagnosticEffect = {
13734
13832
  };
13735
13833
 
13736
13834
  const queues = {};
13835
+ const cursorUndoLimit = 100;
13836
+ const selectionsEqual = (left, right) => {
13837
+ if (left === right) {
13838
+ return true;
13839
+ }
13840
+ if (left.length !== right.length) {
13841
+ return false;
13842
+ }
13843
+ for (let i = 0; i < left.length; i++) {
13844
+ if (left[i] !== right[i]) {
13845
+ return false;
13846
+ }
13847
+ }
13848
+ return true;
13849
+ };
13737
13850
  const saveAfterDelay = async (uid, token) => {
13738
13851
  if (!get$8(uid)) {
13739
13852
  consume(uid, token);
@@ -13762,7 +13875,7 @@ const saveAfterDelay = async (uid, token) => {
13762
13875
  // TODO wrap commands globally, not per editor
13763
13876
  // TODO only store editor state in editor worker, not in renderer worker also
13764
13877
 
13765
- const wrapCommand = fn => async (uid, ...args) => {
13878
+ const wrapCommand = (fn, preservesTypingCoalescing = false) => async (uid, ...args) => {
13766
13879
  const initialInstance = get$8(uid);
13767
13880
  const queueKey = initialInstance?.newState.uri || uid;
13768
13881
  const previous = queues[queueKey];
@@ -13777,7 +13890,34 @@ const wrapCommand = fn => async (uid, ...args) => {
13777
13890
  try {
13778
13891
  const oldInstance = get$8(uid);
13779
13892
  const state = oldInstance.newState;
13780
- const newEditor = await fn(state, ...args);
13893
+ const {
13894
+ cursorUndoStack,
13895
+ initial,
13896
+ isSelecting,
13897
+ lines,
13898
+ modified,
13899
+ redoStack,
13900
+ selections,
13901
+ undoStack,
13902
+ uri
13903
+ } = state;
13904
+ const commandResult = await fn(state, ...args);
13905
+ let newEditor = !preservesTypingCoalescing && commandResult.canCoalesceTyping ? {
13906
+ ...commandResult,
13907
+ canCoalesceTyping: false
13908
+ } : commandResult;
13909
+ if (lines !== newEditor.lines && newEditor.cursorUndoStack?.length) {
13910
+ newEditor = {
13911
+ ...newEditor,
13912
+ cursorUndoStack: []
13913
+ };
13914
+ } else if (selections && newEditor.selections && !isSelecting && newEditor.cursorUndoStack === cursorUndoStack && (!selectionsEqual(selections, newEditor.selections) || newEditor.isSelecting)) {
13915
+ const previousCursorUndoStack = cursorUndoStack || [];
13916
+ newEditor = {
13917
+ ...newEditor,
13918
+ cursorUndoStack: [...previousCursorUndoStack.slice(1 - cursorUndoLimit), new Uint32Array(selections)]
13919
+ };
13920
+ }
13781
13921
  if (state === newEditor) {
13782
13922
  return newEditor;
13783
13923
  }
@@ -13791,14 +13931,6 @@ const wrapCommand = fn => async (uid, ...args) => {
13791
13931
  }
13792
13932
  set$8(uid, state, finalEditor);
13793
13933
  }
13794
- const {
13795
- initial,
13796
- lines,
13797
- modified,
13798
- redoStack,
13799
- undoStack,
13800
- uri
13801
- } = state;
13802
13934
  if (!initial && uri === finalEditor.uri && (lines !== finalEditor.lines || modified !== finalEditor.modified || redoStack !== finalEditor.redoStack || undoStack !== finalEditor.undoStack)) {
13803
13935
  for (const key of getKeys$2()) {
13804
13936
  const otherUid = Number(key);
@@ -13877,6 +14009,7 @@ const commandMap = {
13877
14009
  'Editor.cursorPageDown': wrapCommand(cursorPageDown),
13878
14010
  'Editor.cursorRight': wrapCommand(cursorCharacterRight),
13879
14011
  'Editor.cursorSet': wrapCommand(cursorSet),
14012
+ 'Editor.cursorUndo': wrapCommand(cursorUndo$1),
13880
14013
  'Editor.cursorUp': wrapCommand(cursorUp),
13881
14014
  'Editor.cursorWordLeft': wrapCommand(cursorWordLeft),
13882
14015
  'Editor.cursorWordPartLeft': wrapCommand(cursorWordPartLeft),
@@ -14029,8 +14162,8 @@ const commandMap = {
14029
14162
  'Editor.toggleBreakpoint': wrapCommand(toggleBreakpoint),
14030
14163
  'Editor.toggleComment': wrapCommand(toggleComment),
14031
14164
  'Editor.toggleLineComment': wrapCommand(editorToggleLineComment),
14032
- 'Editor.type': wrapCommand(type),
14033
- 'Editor.typeWithAutoClosing': wrapCommand(typeWithAutoClosing),
14165
+ 'Editor.type': wrapCommand(type, true),
14166
+ 'Editor.typeWithAutoClosing': wrapCommand(typeWithAutoClosing, true),
14034
14167
  'Editor.undo': wrapCommand(undo),
14035
14168
  'Editor.unfold': wrapCommand(unfold),
14036
14169
  'Editor.unIndent': wrapCommand(editorUnindent),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/editor-worker",
3
- "version": "19.29.11",
3
+ "version": "19.29.13",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git@github.com:lvce-editor/editor-worker.git"