@lvce-editor/editor-worker 19.20.1 → 19.22.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 +1320 -700
  2. package/package.json +1 -1
@@ -1626,6 +1626,7 @@ const Tab$1 = 2;
1626
1626
  const Enter = 3;
1627
1627
  const Escape = 8;
1628
1628
  const Space$1 = 9;
1629
+ const PageDown = 11;
1629
1630
  const End = 255;
1630
1631
  const Home = 12;
1631
1632
  const LeftArrow = 13;
@@ -1648,6 +1649,7 @@ const KeyZ = 54;
1648
1649
  const F2 = 58;
1649
1650
  const F3 = 59;
1650
1651
  const F4 = 60;
1652
+ const F9 = 65;
1651
1653
  const F12 = 68;
1652
1654
  const Period = 87;
1653
1655
  const Slash$1 = 88;
@@ -1954,6 +1956,7 @@ const createEditor2 = (id, uri, x, y, width, height, platform, assetDir) => {
1954
1956
  const editor = {
1955
1957
  additionalFocus: 0,
1956
1958
  assetDir,
1959
+ breakPoints: [],
1957
1960
  charWidth: 0,
1958
1961
  columnWidth: 0,
1959
1962
  completionState: '',
@@ -1974,6 +1977,7 @@ const createEditor2 = (id, uri, x, y, width, height, platform, assetDir) => {
1974
1977
  focus: 0,
1975
1978
  focused: false,
1976
1979
  focusKey: Empty,
1980
+ foldingRanges: [],
1977
1981
  fontFamily: '',
1978
1982
  fontSize: 0,
1979
1983
  fontWeight: 0,
@@ -2029,6 +2033,7 @@ const createEditor2 = (id, uri, x, y, width, height, platform, assetDir) => {
2029
2033
  undoStack: [],
2030
2034
  uri,
2031
2035
  validLines: [],
2036
+ visibleLineIndices: [],
2032
2037
  visualDecorations: [],
2033
2038
  widgets: [],
2034
2039
  width,
@@ -2105,6 +2110,234 @@ const clamp = (num, min, max) => {
2105
2110
  return Math.min(Math.max(num, min), max);
2106
2111
  };
2107
2112
 
2113
+ const getScrollBarOffset = (delta, finalDelta, size, scrollBarSize) => {
2114
+ const scrollBarOffset = delta / finalDelta * (size - scrollBarSize);
2115
+ if (!Number.isFinite(scrollBarOffset)) {
2116
+ return 0;
2117
+ }
2118
+ return scrollBarOffset;
2119
+ };
2120
+ const getScrollBarY = getScrollBarOffset;
2121
+
2122
+ const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
2123
+ if (size >= contentSize) {
2124
+ return 0;
2125
+ }
2126
+ return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
2127
+ };
2128
+
2129
+ const getScrollBarWidth = (width, longestLineWidth) => {
2130
+ if (width > longestLineWidth) {
2131
+ return 0;
2132
+ }
2133
+ return width ** 2 / longestLineWidth;
2134
+ };
2135
+
2136
+ const getNewDeltaPercent = (height, scrollBarHeight, relativeY) => {
2137
+ const halfScrollBarHeight = scrollBarHeight / 2;
2138
+ if (relativeY <= halfScrollBarHeight) {
2139
+ // clicked at top
2140
+ return {
2141
+ handleOffset: relativeY,
2142
+ percent: 0
2143
+ };
2144
+ }
2145
+ if (relativeY <= height - halfScrollBarHeight) {
2146
+ // clicked in middle
2147
+ return {
2148
+ handleOffset: halfScrollBarHeight,
2149
+ percent: (relativeY - halfScrollBarHeight) / (height - scrollBarHeight)
2150
+ };
2151
+ }
2152
+ // clicked at bottom
2153
+ return {
2154
+ handleOffset: scrollBarHeight - height + relativeY,
2155
+ percent: 1
2156
+ };
2157
+ };
2158
+
2159
+ const getSortedRanges = ranges => {
2160
+ return ranges.toSorted((a, b) => a.start - b.start || b.end - a.end);
2161
+ };
2162
+ const getUnhiddenRow = (rowIndex, previousRowIndex, lineCount, ranges) => {
2163
+ for (const range of ranges) {
2164
+ if (rowIndex > range.start && rowIndex <= range.end) {
2165
+ return rowIndex >= previousRowIndex ? Math.min(range.end + 1, lineCount - 1) : range.start;
2166
+ }
2167
+ }
2168
+ return rowIndex;
2169
+ };
2170
+ const getVisibleLineCount = (lineCount, ranges) => {
2171
+ let hidden = 0;
2172
+ let hiddenUntil = -1;
2173
+ for (const range of getSortedRanges(ranges)) {
2174
+ const start = Math.max(range.start + 1, hiddenUntil + 1);
2175
+ const end = Math.min(range.end, lineCount - 1);
2176
+ if (start <= end) {
2177
+ hidden += end - start + 1;
2178
+ hiddenUntil = end;
2179
+ }
2180
+ }
2181
+ return lineCount - hidden;
2182
+ };
2183
+ const getVisualRowForDocumentRow = (rowIndex, ranges) => {
2184
+ let hiddenBefore = 0;
2185
+ for (const range of getSortedRanges(ranges)) {
2186
+ if (rowIndex <= range.start) {
2187
+ break;
2188
+ }
2189
+ if (rowIndex <= range.end) {
2190
+ return range.start - hiddenBefore;
2191
+ }
2192
+ hiddenBefore += range.end - range.start;
2193
+ }
2194
+ return rowIndex - hiddenBefore;
2195
+ };
2196
+ const getDocumentRowForVisualRow = (visualRow, ranges) => {
2197
+ let documentRow = visualRow;
2198
+ let hiddenBefore = 0;
2199
+ for (const range of getSortedRanges(ranges)) {
2200
+ const rangeVisualRow = range.start - hiddenBefore;
2201
+ if (visualRow <= rangeVisualRow) {
2202
+ break;
2203
+ }
2204
+ const hiddenCount = range.end - range.start;
2205
+ documentRow += hiddenCount;
2206
+ hiddenBefore += hiddenCount;
2207
+ }
2208
+ return documentRow;
2209
+ };
2210
+ const getViewportLineIndices = (lineCount, ranges, startVisualRow, numberOfVisibleLines) => {
2211
+ const visibleLineCount = getVisibleLineCount(lineCount, ranges);
2212
+ const endVisualRow = Math.min(startVisualRow + numberOfVisibleLines, visibleLineCount);
2213
+ const result = [];
2214
+ for (let visualRow = startVisualRow; visualRow < endVisualRow; visualRow++) {
2215
+ result.push(getDocumentRowForVisualRow(visualRow, ranges));
2216
+ }
2217
+ return result;
2218
+ };
2219
+ const updateLayout = (editor, foldingRanges) => {
2220
+ const {
2221
+ height,
2222
+ itemHeight,
2223
+ lines,
2224
+ minimumSliderSize,
2225
+ numberOfVisibleLines,
2226
+ rowHeight
2227
+ } = editor;
2228
+ const visibleLineCount = getVisibleLineCount(lines.length, foldingRanges);
2229
+ const finalY = Math.max(visibleLineCount - numberOfVisibleLines, 0);
2230
+ const finalDeltaY = finalY * itemHeight;
2231
+ const deltaY = clamp(editor.deltaY, 0, finalDeltaY);
2232
+ const startVisualRow = Math.floor(deltaY / itemHeight);
2233
+ const visibleLineIndices = getViewportLineIndices(lines.length, foldingRanges, startVisualRow, numberOfVisibleLines);
2234
+ const minLineY = visibleLineIndices[0] ?? 0;
2235
+ const maxLineY = visibleLineIndices.length === 0 ? 0 : visibleLineIndices.at(-1) + 1;
2236
+ const contentHeight = visibleLineCount * rowHeight;
2237
+ const scrollBarHeight = getScrollBarSize(height, contentHeight, minimumSliderSize);
2238
+ const scrollBarY = getScrollBarY(deltaY, finalDeltaY, height, scrollBarHeight);
2239
+ return {
2240
+ ...editor,
2241
+ deltaY,
2242
+ finalDeltaY,
2243
+ finalY,
2244
+ foldingRanges,
2245
+ maxLineY,
2246
+ minLineY,
2247
+ scrollBarHeight,
2248
+ scrollBarY,
2249
+ visibleLineIndices
2250
+ };
2251
+ };
2252
+ const addRange = (ranges, range) => {
2253
+ if (ranges.some(existing => existing.start <= range.start && existing.end >= range.end)) {
2254
+ return ranges;
2255
+ }
2256
+ const remainingRanges = ranges.filter(existing => range.start > existing.start || range.end < existing.end);
2257
+ return getSortedRanges([...remainingRanges, range]);
2258
+ };
2259
+ const removeRangeAt = (ranges, rowIndex) => {
2260
+ let bestIndex = -1;
2261
+ let bestSize = Infinity;
2262
+ for (let i = 0; i < ranges.length; i++) {
2263
+ if (ranges[i].start === rowIndex) {
2264
+ bestIndex = i;
2265
+ break;
2266
+ }
2267
+ const range = ranges[i];
2268
+ if (rowIndex >= range.start && rowIndex <= range.end && range.end - range.start < bestSize) {
2269
+ bestIndex = i;
2270
+ bestSize = range.end - range.start;
2271
+ }
2272
+ }
2273
+ return bestIndex === -1 ? ranges : ranges.filter((_, index) => index !== bestIndex);
2274
+ };
2275
+ const scanLine = (line, row, stack, ranges, state) => {
2276
+ for (let column = 0; column < line.length; column++) {
2277
+ const character = line[column];
2278
+ const next = line[column + 1];
2279
+ if (state.blockComment) {
2280
+ if (character === '*' && next === '/') {
2281
+ state.blockComment = false;
2282
+ column++;
2283
+ }
2284
+ continue;
2285
+ }
2286
+ if (state.quote) {
2287
+ if (state.escaped) {
2288
+ state.escaped = false;
2289
+ } else if (character === '\\') {
2290
+ state.escaped = true;
2291
+ } else if (character === state.quote) {
2292
+ state.quote = '';
2293
+ }
2294
+ continue;
2295
+ }
2296
+ if (character === '/' && next === '/') {
2297
+ return;
2298
+ }
2299
+ if (character === '/' && next === '*') {
2300
+ state.blockComment = true;
2301
+ column++;
2302
+ continue;
2303
+ }
2304
+ if (["'", '"', '`'].includes(character)) {
2305
+ state.quote = character;
2306
+ continue;
2307
+ }
2308
+ if (character === '{') {
2309
+ stack.push(row);
2310
+ continue;
2311
+ }
2312
+ if (character === '}') {
2313
+ const start = stack.pop();
2314
+ if (start !== undefined && start < row) {
2315
+ ranges.push({
2316
+ end: row,
2317
+ start
2318
+ });
2319
+ }
2320
+ }
2321
+ }
2322
+ if (state.quote !== '`') {
2323
+ state.quote = '';
2324
+ state.escaped = false;
2325
+ }
2326
+ };
2327
+ const findRange = (lines, rowIndex) => {
2328
+ const stack = [];
2329
+ const ranges = [];
2330
+ const state = {
2331
+ blockComment: false,
2332
+ escaped: false,
2333
+ quote: ''
2334
+ };
2335
+ for (let row = 0; row < lines.length; row++) {
2336
+ scanLine(lines[row], row, stack, ranges, state);
2337
+ }
2338
+ return ranges.filter(range => range.start <= rowIndex && rowIndex <= range.end).toSorted((a, b) => a.end - a.start - (b.end - b.start))[0];
2339
+ };
2340
+
2108
2341
  const Link$1 = 'Link';
2109
2342
  const EditorGoToDefinitionLink = 'EditorGoToDefinitionLink';
2110
2343
  const Function = 'Function';
@@ -3089,11 +3322,19 @@ const getVisible$1 = async (editor, syncIncremental) => {
3089
3322
  charWidth,
3090
3323
  deltaX,
3091
3324
  lines,
3092
- minLineY,
3093
- numberOfVisibleLines,
3094
3325
  width
3095
3326
  } = editor;
3096
- const maxLineY = Math.min(minLineY + numberOfVisibleLines, lines.length);
3327
+ const visibleLineIndices = editor.visibleLineIndices || Array.from({
3328
+ length: Math.min(editor.numberOfVisibleLines, lines.length - editor.minLineY)
3329
+ }, (_, index) => editor.minLineY + index);
3330
+ if (visibleLineIndices.length === 0) {
3331
+ return {
3332
+ differences: [],
3333
+ textInfos: []
3334
+ };
3335
+ }
3336
+ const minLineY = visibleLineIndices[0];
3337
+ const maxLineY = visibleLineIndices.at(-1) + 1;
3097
3338
  // @ts-ignore
3098
3339
  let {
3099
3340
  embeddedResults,
@@ -3113,58 +3354,13 @@ const getVisible$1 = async (editor, syncIncremental) => {
3113
3354
  const minLineOffset = await offsetAtSync(editor, minLineY, 0);
3114
3355
  const averageCharWidth = charWidth;
3115
3356
  const {
3116
- differences,
3117
- result
3357
+ differences: allDifferences,
3358
+ result: allTextInfos
3118
3359
  } = getLineInfosViewport(editor, tokens, embeddedResults, minLineY, maxLineY, minLineOffset, width, deltaX, averageCharWidth);
3360
+ const relativeIndices = visibleLineIndices.map(rowIndex => rowIndex - minLineY);
3119
3361
  return {
3120
- differences,
3121
- textInfos: result
3122
- };
3123
- };
3124
-
3125
- const getScrollBarOffset = (delta, finalDelta, size, scrollBarSize) => {
3126
- const scrollBarOffset = delta / finalDelta * (size - scrollBarSize);
3127
- if (!Number.isFinite(scrollBarOffset)) {
3128
- return 0;
3129
- }
3130
- return scrollBarOffset;
3131
- };
3132
- const getScrollBarY = getScrollBarOffset;
3133
-
3134
- const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
3135
- if (size >= contentSize) {
3136
- return 0;
3137
- }
3138
- return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
3139
- };
3140
-
3141
- const getScrollBarWidth = (width, longestLineWidth) => {
3142
- if (width > longestLineWidth) {
3143
- return 0;
3144
- }
3145
- return width ** 2 / longestLineWidth;
3146
- };
3147
-
3148
- const getNewDeltaPercent = (height, scrollBarHeight, relativeY) => {
3149
- const halfScrollBarHeight = scrollBarHeight / 2;
3150
- if (relativeY <= halfScrollBarHeight) {
3151
- // clicked at top
3152
- return {
3153
- handleOffset: relativeY,
3154
- percent: 0
3155
- };
3156
- }
3157
- if (relativeY <= height - halfScrollBarHeight) {
3158
- // clicked in middle
3159
- return {
3160
- handleOffset: halfScrollBarHeight,
3161
- percent: (relativeY - halfScrollBarHeight) / (height - scrollBarHeight)
3162
- };
3163
- }
3164
- // clicked at bottom
3165
- return {
3166
- handleOffset: scrollBarHeight - height + relativeY,
3167
- percent: 1
3362
+ differences: relativeIndices.map(index => allDifferences[index]),
3363
+ textInfos: relativeIndices.map(index => allTextInfos[index])
3168
3364
  };
3169
3365
  };
3170
3366
 
@@ -3194,15 +3390,22 @@ const setDeltaY$2 = async (state, value) => {
3194
3390
  if (deltaY === newDeltaY) {
3195
3391
  return state;
3196
3392
  }
3197
- const newMinLineY = Math.floor(newDeltaY / itemHeight);
3198
- const newMaxLineY = newMinLineY + numberOfVisibleLines;
3199
- const scrollBarY = getScrollBarY(newDeltaY, finalDeltaY, height, scrollBarHeight);
3200
- const newEditor1 = {
3393
+ const minLineY = Math.floor(newDeltaY / itemHeight);
3394
+ const maxLineY = minLineY + numberOfVisibleLines;
3395
+ const newEditor1 = state.foldingRanges?.length > 0 ? updateLayout({
3396
+ ...state,
3397
+ deltaY: newDeltaY
3398
+ }, state.foldingRanges) : {
3201
3399
  ...state,
3202
3400
  deltaY: newDeltaY,
3203
- maxLineY: newMaxLineY,
3204
- minLineY: newMinLineY,
3205
- scrollBarY
3401
+ maxLineY,
3402
+ minLineY,
3403
+ scrollBarY: getScrollBarY(newDeltaY, finalDeltaY, height, scrollBarHeight),
3404
+ ...('visibleLineIndices' in state && {
3405
+ visibleLineIndices: Array.from({
3406
+ length: Math.max(Math.min(maxLineY, state.lines.length) - minLineY, 0)
3407
+ }, (_, index) => minLineY + index)
3408
+ })
3206
3409
  };
3207
3410
  const syncIncremental = getEnabled();
3208
3411
  const {
@@ -3472,29 +3675,41 @@ const resize = (state, dimensions, columnWidth = state.columnWidth) => {
3472
3675
  const width = dimensions.width ?? state.width;
3473
3676
  const height = dimensions.height ?? state.height;
3474
3677
  const numberOfVisibleLines = Math.floor(height / state.itemHeight);
3475
- const total = state.lines.length;
3476
- const finalY = Math.max(total - numberOfVisibleLines, 0);
3477
- const finalDeltaY = finalY * state.itemHeight;
3478
- const deltaY = Math.min(state.deltaY, finalDeltaY);
3479
- const minLineY = Math.floor(deltaY / state.itemHeight);
3480
- const maxLineY = Math.min(minLineY + numberOfVisibleLines, total);
3481
- const contentHeight = total * state.rowHeight;
3482
- const scrollBarHeight = getScrollBarSize(height, contentHeight, state.minimumSliderSize);
3483
- return {
3678
+ if (!('foldingRanges' in state)) {
3679
+ const total = state.lines.length;
3680
+ const finalY = Math.max(total - numberOfVisibleLines, 0);
3681
+ const finalDeltaY = finalY * state.itemHeight;
3682
+ const deltaY = Math.min(state.deltaY, finalDeltaY);
3683
+ const minLineY = Math.floor(deltaY / state.itemHeight);
3684
+ const maxLineY = Math.min(minLineY + numberOfVisibleLines, total);
3685
+ const contentHeight = total * state.rowHeight;
3686
+ const scrollBarHeight = getScrollBarSize(height, contentHeight, state.minimumSliderSize);
3687
+ return {
3688
+ ...state,
3689
+ columnWidth,
3690
+ deltaY,
3691
+ finalDeltaY,
3692
+ finalY,
3693
+ height,
3694
+ maxLineY,
3695
+ minLineY,
3696
+ numberOfVisibleLines,
3697
+ scrollBarHeight,
3698
+ width,
3699
+ x,
3700
+ y
3701
+ };
3702
+ }
3703
+ const resized = {
3484
3704
  ...state,
3485
3705
  columnWidth,
3486
- deltaY,
3487
- finalDeltaY,
3488
- finalY,
3489
3706
  height,
3490
- maxLineY,
3491
- minLineY,
3492
3707
  numberOfVisibleLines,
3493
- scrollBarHeight,
3494
3708
  width,
3495
3709
  x,
3496
3710
  y
3497
3711
  };
3712
+ return updateLayout(resized, state.foldingRanges);
3498
3713
  };
3499
3714
 
3500
3715
  const splitLines = lines => {
@@ -3587,10 +3802,6 @@ const getX = async (line, column, fontWeight, fontSize, fontFamily, isMonospaceF
3587
3802
  return textWidth - halfCursorWidth + difference;
3588
3803
  };
3589
3804
 
3590
- const getY = (row, minLineY, rowHeight) => {
3591
- return (row - minLineY) * rowHeight;
3592
- };
3593
-
3594
3805
  const px = value => {
3595
3806
  return `${value}px`;
3596
3807
  };
@@ -3699,12 +3910,15 @@ const getVisible = async editor => {
3699
3910
  const {
3700
3911
  charWidth,
3701
3912
  cursorWidth,
3913
+ deltaY,
3702
3914
  differences,
3703
3915
  focused,
3916
+ foldingRanges = [],
3704
3917
  fontFamily,
3705
3918
  fontSize,
3706
3919
  fontWeight,
3707
3920
  isMonospaceFont,
3921
+ itemHeight,
3708
3922
  letterSpacing,
3709
3923
  lines,
3710
3924
  maxLineY,
@@ -3712,26 +3926,35 @@ const getVisible = async editor => {
3712
3926
  rowHeight,
3713
3927
  selections,
3714
3928
  tabSize,
3929
+ visibleLineIndices,
3715
3930
  width
3716
3931
  } = editor;
3717
3932
  const averageCharWidth = charWidth;
3718
3933
  const halfCursorWidth = cursorWidth / 2;
3934
+ const actualVisibleLineIndices = visibleLineIndices || Array.from({
3935
+ length: maxLineY - minLineY
3936
+ }, (_, index) => minLineY + index);
3937
+ const startVisualRow = itemHeight ? Math.floor(deltaY / itemHeight) : getVisualRowForDocumentRow(minLineY, foldingRanges);
3938
+ const endVisualRow = startVisualRow + actualVisibleLineIndices.length;
3939
+ const getRelativeRow = rowIndex => getVisualRowForDocumentRow(rowIndex, foldingRanges) - startVisualRow;
3719
3940
  for (let i = 0; i < selections.length; i += 4) {
3720
3941
  const [selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn, reversed] = getSelectionPairs(selections, i);
3721
- if (selectionEndRow < minLineY || selectionStartRow > maxLineY) {
3942
+ const selectionStartVisualRow = getVisualRowForDocumentRow(selectionStartRow, foldingRanges);
3943
+ const selectionEndVisualRow = getVisualRowForDocumentRow(selectionEndRow, foldingRanges);
3944
+ if (selectionEndVisualRow < startVisualRow || selectionStartVisualRow >= endVisualRow) {
3722
3945
  continue;
3723
3946
  }
3724
- const relativeEndLineRow = selectionEndRow - minLineY;
3947
+ const relativeEndLineRow = getRelativeRow(selectionEndRow);
3725
3948
  const endLineDifference = differences[relativeEndLineRow];
3726
3949
  const endLine = lines[selectionEndRow];
3727
3950
  const endLineEndX = await getX(endLine, selectionEndColumn, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, endLineDifference);
3728
- const endLineY = getY(selectionEndRow, minLineY, rowHeight);
3951
+ const endLineY = relativeEndLineRow * rowHeight;
3729
3952
  if (isEmpty(selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) && endLineEndX > 0) {
3730
3953
  visibleCursors.push(endLineEndX, endLineY);
3731
3954
  continue;
3732
3955
  }
3733
- const startLineY = getY(selectionStartRow, minLineY, rowHeight);
3734
- const startLineYRelative = selectionStartRow - minLineY;
3956
+ const startLineYRelative = getRelativeRow(selectionStartRow);
3957
+ const startLineY = startLineYRelative * rowHeight;
3735
3958
  const startLineDifference = differences[startLineYRelative];
3736
3959
  if (selectionStartRow === selectionEndRow) {
3737
3960
  const startX = await getX(endLine, selectionStartColumn, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, startLineDifference);
@@ -3743,28 +3966,27 @@ const getVisible = async editor => {
3743
3966
  const selectionWidth = endLineEndX - startX;
3744
3967
  visibleSelections.push(startX, startLineY, selectionWidth, rowHeight);
3745
3968
  } else {
3746
- if (selectionStartRow >= minLineY) {
3969
+ if (selectionStartVisualRow >= startVisualRow) {
3747
3970
  const startLine = lines[selectionStartRow];
3748
3971
  const startLineStartX = await getX(startLine, selectionStartColumn, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, startLineDifference);
3749
3972
  const startLineEndX = await getX(startLine, startLine.length, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, startLineDifference);
3750
- const startLineStartY = getY(selectionStartRow, minLineY, rowHeight);
3973
+ const startLineStartY = startLineYRelative * rowHeight;
3751
3974
  const selectionWidth = startLineEndX - startLineStartX;
3752
3975
  if (reversed) {
3753
3976
  visibleCursors.push(startLineStartX, startLineStartY);
3754
3977
  }
3755
3978
  visibleSelections.push(startLineStartX, startLineStartY, selectionWidth, rowHeight);
3756
3979
  }
3757
- const iMin = Math.max(selectionStartRow + 1, minLineY);
3758
- const iMax = Math.min(selectionEndRow, maxLineY);
3759
- for (let i = iMin; i < iMax; i++) {
3760
- const currentLine = lines[i];
3761
- const currentLineY = getY(i, minLineY, rowHeight);
3762
- const relativeLine = i - minLineY;
3980
+ const selectedVisibleRows = actualVisibleLineIndices.filter(rowIndex => rowIndex > selectionStartRow && rowIndex < selectionEndRow);
3981
+ for (const rowIndex of selectedVisibleRows) {
3982
+ const currentLine = lines[rowIndex];
3983
+ const relativeLine = getRelativeRow(rowIndex);
3984
+ const currentLineY = relativeLine * rowHeight;
3763
3985
  const difference = differences[relativeLine];
3764
3986
  const selectionWidth = await getX(currentLine, currentLine.length, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, difference);
3765
3987
  visibleSelections.push(0, currentLineY, selectionWidth, rowHeight);
3766
3988
  }
3767
- if (selectionEndRow <= maxLineY) {
3989
+ if (selectionEndVisualRow < endVisualRow) {
3768
3990
  const selectionWidth = endLineEndX;
3769
3991
  visibleSelections.push(0, endLineY, selectionWidth, rowHeight);
3770
3992
  if (!reversed) {
@@ -3809,13 +4031,72 @@ const getSelectionFromChange = change => {
3809
4031
  };
3810
4032
  const setSelections$1 = (editor, selections) => {
3811
4033
  object(editor);
3812
- // Assert.uint32array(selections)
3813
- return {
4034
+ const {
4035
+ foldingRanges = []
4036
+ } = editor;
4037
+ if ('foldingRanges' in editor) {
4038
+ const normalizedSelections = foldingRanges.length === 0 ? selections : map(selections, (result, index, startRow, startColumn, endRow, endColumn) => {
4039
+ const previousRow = editor.selections[index + 2] ?? endRow;
4040
+ result[index] = getUnhiddenRow(startRow, previousRow, editor.lines.length, foldingRanges);
4041
+ result[index + 1] = startColumn;
4042
+ result[index + 2] = getUnhiddenRow(endRow, previousRow, editor.lines.length, foldingRanges);
4043
+ result[index + 3] = endColumn;
4044
+ });
4045
+ const rowIndex = normalizedSelections[editor.primarySelectionIndex || 0];
4046
+ const visualRow = getVisualRowForDocumentRow(rowIndex, foldingRanges);
4047
+ const startVisualRow = Math.floor(editor.deltaY / editor.itemHeight);
4048
+ const endVisualRow = startVisualRow + editor.numberOfVisibleLines;
4049
+ if (visualRow >= startVisualRow && visualRow < endVisualRow) {
4050
+ return {
4051
+ ...editor,
4052
+ selections: normalizedSelections
4053
+ };
4054
+ }
4055
+ const desiredStartVisualRow = visualRow < startVisualRow ? visualRow : visualRow - editor.numberOfVisibleLines + 1;
4056
+ return updateLayout({
4057
+ ...editor,
4058
+ deltaY: desiredStartVisualRow * editor.itemHeight,
4059
+ selections: normalizedSelections
4060
+ }, foldingRanges);
4061
+ }
4062
+ const newEditor = {
3814
4063
  ...editor,
3815
4064
  selections
3816
4065
  };
3817
- // editor.selections = selections
3818
- // GlobalEventBus.emitEvent('editor.selectionChange', editor, selections)
4066
+ const {
4067
+ maxLineY,
4068
+ minLineY,
4069
+ numberOfVisibleLines
4070
+ } = editor;
4071
+ if (maxLineY === undefined || minLineY === undefined || numberOfVisibleLines <= 0) {
4072
+ return newEditor;
4073
+ }
4074
+ const rowIndex = selections[editor.primarySelectionIndex || 0];
4075
+ if (rowIndex === undefined) {
4076
+ return newEditor;
4077
+ }
4078
+ if (rowIndex >= minLineY && rowIndex < maxLineY) {
4079
+ return newEditor;
4080
+ }
4081
+ const {
4082
+ finalDeltaY,
4083
+ height,
4084
+ itemHeight,
4085
+ lines,
4086
+ scrollBarHeight
4087
+ } = editor;
4088
+ const desiredMinLineY = rowIndex < minLineY ? rowIndex : rowIndex - numberOfVisibleLines + 1;
4089
+ const deltaY = clamp(desiredMinLineY * itemHeight, 0, finalDeltaY);
4090
+ const newMinLineY = Math.floor(deltaY / itemHeight);
4091
+ const newMaxLineY = Math.min(newMinLineY + numberOfVisibleLines, lines.length);
4092
+ const scrollBarY = getScrollBarY(deltaY, finalDeltaY, height, scrollBarHeight);
4093
+ return {
4094
+ ...newEditor,
4095
+ deltaY,
4096
+ maxLineY: newMaxLineY,
4097
+ minLineY: newMinLineY,
4098
+ scrollBarY
4099
+ };
3819
4100
  };
3820
4101
 
3821
4102
  // TODO maybe only accept sorted selection edits in the first place
@@ -3868,6 +4149,13 @@ const applyAutoClosingRangesEdit = (editor, changes) => {
3868
4149
  const scheduleSelections = (editor, selectionEdits) => {
3869
4150
  return setSelections$1(editor, selectionEdits);
3870
4151
  };
4152
+ const updateLines = (editor, lines) => {
4153
+ const newEditor = {
4154
+ ...editor,
4155
+ lines
4156
+ };
4157
+ return 'foldingRanges' in editor ? updateLayout(newEditor, []) : newEditor;
4158
+ };
3871
4159
 
3872
4160
  /**
3873
4161
  * TODO make this synchronous maybe?
@@ -3883,10 +4171,7 @@ const scheduleDocumentAndCursorsSelections = async (editor, changes, selectionCh
3883
4171
  return editor;
3884
4172
  }
3885
4173
  const newLines = applyEdits(editor, changes);
3886
- const partialNewEditor = {
3887
- ...editor,
3888
- lines: newLines
3889
- };
4174
+ const partialNewEditor = updateLines(editor, newLines);
3890
4175
  const newSelections = selectionChanges || applyEdit$1(partialNewEditor, changes);
3891
4176
  // TODO should separate rendering from business logic somehow
3892
4177
  // currently hard to test because need to mock editor height, top, left,
@@ -3956,10 +4241,7 @@ const scheduleDocumentAndCursorsSelectionIsUndo = async (editor, changes) => {
3956
4241
  return editor;
3957
4242
  }
3958
4243
  const newLines = applyEdits(editor, changes);
3959
- const partialNewEditor = {
3960
- ...editor,
3961
- lines: newLines
3962
- };
4244
+ const partialNewEditor = updateLines(editor, newLines);
3963
4245
  const newSelections = applyEdit$1(partialNewEditor, changes);
3964
4246
  const invalidStartIndex = Math.min(editor.invalidStartIndex, changes[0].start.rowIndex);
3965
4247
  const newEditor = {
@@ -4008,9 +4290,8 @@ const scheduleDocument = async (editor, changes) => {
4008
4290
  // const scrollBarHeight = editor.scrollBarHeight
4009
4291
 
4010
4292
  const newEditor = {
4011
- ...editor,
4293
+ ...updateLines(editor, newLines),
4012
4294
  invalidStartIndex,
4013
- lines: newLines,
4014
4295
  redoStack: [],
4015
4296
  undoStack: [...editor.undoStack, changes]
4016
4297
  };
@@ -4059,28 +4340,14 @@ const setBounds = (editor, x, y, width, height, columnWidth) => {
4059
4340
  };
4060
4341
  const setText$1 = (editor, text) => {
4061
4342
  const lines = splitLines(text);
4062
- const {
4063
- itemHeight,
4064
- minimumSliderSize,
4065
- numberOfVisibleLines
4066
- } = editor;
4067
- const total = lines.length;
4068
- const maxLineY = Math.min(numberOfVisibleLines, total);
4069
- const finalY = Math.max(total - numberOfVisibleLines, 0);
4070
- const finalDeltaY = finalY * itemHeight;
4071
- const contentHeight = lines.length * editor.rowHeight;
4072
- const scrollBarHeight = getScrollBarSize(editor.height, contentHeight, minimumSliderSize);
4073
- return {
4343
+ return updateLayout({
4074
4344
  ...editor,
4075
- finalDeltaY,
4076
- finalY,
4077
- lines,
4078
- maxLineY,
4079
- scrollBarHeight
4080
- };
4345
+ lines
4346
+ }, []);
4081
4347
  };
4082
4348
 
4083
4349
  const emptyEditor = {
4350
+ breakPoints: [],
4084
4351
  cursorInfos: [],
4085
4352
  debugEnabled: false,
4086
4353
  decorations: [],
@@ -4090,6 +4357,7 @@ const emptyEditor = {
4090
4357
  differences: [],
4091
4358
  embeds: [],
4092
4359
  focused: false,
4360
+ foldingRanges: [],
4093
4361
  hasListener: false,
4094
4362
  height: 0,
4095
4363
  highlightedLine: -1,
@@ -4118,6 +4386,7 @@ const emptyEditor = {
4118
4386
  tokenizerId: 0,
4119
4387
  undoStack: [],
4120
4388
  uri: '',
4389
+ visibleLineIndices: [],
4121
4390
  width: 0,
4122
4391
  x: 0,
4123
4392
  y: 0
@@ -4280,6 +4549,10 @@ const getDiagnosticType = diagnostic => {
4280
4549
  return diagnostic.type;
4281
4550
  };
4282
4551
 
4552
+ const getY = (row, minLineY, rowHeight) => {
4553
+ return (row - minLineY) * rowHeight;
4554
+ };
4555
+
4283
4556
  const getVisibleDiagnostics = async (editor, diagnostics) => {
4284
4557
  const visibleDiagnostics = [];
4285
4558
  const {
@@ -4443,6 +4716,7 @@ const createEditor = async ({
4443
4716
  const computedlanguageId = getLanguageId$1(uri, languages);
4444
4717
  const editor = {
4445
4718
  assetDir,
4719
+ breakPoints: [],
4446
4720
  charWidth,
4447
4721
  columnWidth: 0,
4448
4722
  completionState: '',
@@ -4460,6 +4734,7 @@ const createEditor = async ({
4460
4734
  finalY: 0,
4461
4735
  focused: false,
4462
4736
  focusKey: Empty,
4737
+ foldingRanges: [],
4463
4738
  fontFamily,
4464
4739
  fontSize,
4465
4740
  fontWeight,
@@ -4514,6 +4789,7 @@ const createEditor = async ({
4514
4789
  uri,
4515
4790
  useFunctionalRendering,
4516
4791
  validLines: [],
4792
+ visibleLineIndices: [],
4517
4793
  widgets: [],
4518
4794
  width,
4519
4795
  x,
@@ -4565,6 +4841,10 @@ const createEditor = async ({
4565
4841
  });
4566
4842
  };
4567
4843
 
4844
+ const isEqual$4 = (oldState, newState) => {
4845
+ return oldState.additionalFocus === newState.additionalFocus;
4846
+ };
4847
+
4568
4848
  const isEqual$3 = (oldState, newState) => {
4569
4849
  return oldState.rowHeight === newState.rowHeight && oldState.deltaY === newState.deltaY && oldState.finalDeltaY === newState.finalDeltaY && oldState.height === newState.height && oldState.deltaX === newState.deltaX && oldState.longestLineWidth === newState.longestLineWidth && oldState.minimumSliderSize === newState.minimumSliderSize && oldState.width === newState.width && oldState.scrollBarHeight === newState.scrollBarHeight;
4570
4850
  };
@@ -4583,7 +4863,7 @@ const isEqual$2 = (oldState, newState) => {
4583
4863
  };
4584
4864
 
4585
4865
  const isEqual$1 = (oldState, newState) => {
4586
- return oldState.cursorInfos === newState.cursorInfos && oldState.diagnostics === newState.diagnostics && oldState.highlightedLine === newState.highlightedLine && oldState.lineNumbers === newState.lineNumbers && oldState.loadError === newState.loadError && oldState.textInfos === newState.textInfos && oldState.differences === newState.differences && oldState.initial === newState.initial && oldState.selectionInfos === newState.selectionInfos;
4866
+ return oldState.breakPoints === newState.breakPoints && oldState.cursorInfos === newState.cursorInfos && oldState.diagnostics === newState.diagnostics && oldState.highlightedLine === newState.highlightedLine && oldState.lineNumbers === newState.lineNumbers && oldState.loadError === newState.loadError && oldState.textInfos === newState.textInfos && oldState.differences === newState.differences && oldState.initial === newState.initial && oldState.selectionInfos === newState.selectionInfos;
4587
4867
  };
4588
4868
 
4589
4869
  const RenderFocus = 6;
@@ -4591,13 +4871,14 @@ const RenderFocusContext = 7;
4591
4871
  const RenderCss = 11;
4592
4872
  const RenderIncremental = 12;
4593
4873
  const RenderWidgets = 13;
4874
+ const RenderAdditionalFocusContext = 14;
4594
4875
 
4595
4876
  const isEqual = (oldState, newState) => {
4596
4877
  return oldState.widgets === newState.widgets;
4597
4878
  };
4598
4879
 
4599
- const modules = [isEqual$1, isEqual$2, isEqual$2, isEqual$3, isEqual];
4600
- const numbers = [RenderIncremental, RenderFocus, RenderFocusContext, RenderCss, RenderWidgets];
4880
+ const modules = [isEqual$1, isEqual$2, isEqual$2, isEqual$4, isEqual$3, isEqual];
4881
+ const numbers = [RenderIncremental, RenderFocus, RenderFocusContext, RenderAdditionalFocusContext, RenderCss, RenderWidgets];
4601
4882
 
4602
4883
  const diff = (oldState, newState) => {
4603
4884
  const diffResult = [];
@@ -4857,6 +5138,25 @@ const applyWorkspaceEdit = async (editor, changes) => {
4857
5138
  return scheduleDocumentAndCursorsSelections(editor, textChanges);
4858
5139
  };
4859
5140
 
5141
+ const isPersistentWidget = widgetId => {
5142
+ switch (widgetId) {
5143
+ case Find:
5144
+ return true;
5145
+ default:
5146
+ return false;
5147
+ }
5148
+ };
5149
+
5150
+ // TODO widgets should have a persistence property:
5151
+ // 1 = close by click (e.g. completion, hover, source-actions)
5152
+ // 2 = stay open on click (e.g. find)
5153
+ const closeWidgetsMaybe = widgets => {
5154
+ if (widgets.length === 0) {
5155
+ return widgets;
5156
+ }
5157
+ return widgets.filter(widget => isPersistentWidget(widget.id));
5158
+ };
5159
+
4860
5160
  const getFormattingEdits = async editor => {
4861
5161
  const textDocument = {
4862
5162
  documentId: editor.id || editor.uid,
@@ -4988,6 +5288,7 @@ const at = async (editor, eventX, eventY) => {
4988
5288
  charWidth,
4989
5289
  deltaX,
4990
5290
  deltaY,
5291
+ foldingRanges = [],
4991
5292
  fontFamily,
4992
5293
  fontSize,
4993
5294
  fontWeight,
@@ -4999,13 +5300,14 @@ const at = async (editor, eventX, eventY) => {
4999
5300
  x,
5000
5301
  y
5001
5302
  } = editor;
5002
- const rowIndex = Math.floor((eventY - y + deltaY) / rowHeight);
5003
- if (rowIndex < 0) {
5303
+ const visualRowIndex = Math.floor((eventY - y + deltaY) / rowHeight);
5304
+ if (visualRowIndex < 0) {
5004
5305
  return {
5005
5306
  columnIndex: 0,
5006
5307
  rowIndex: 0
5007
5308
  };
5008
5309
  }
5310
+ const rowIndex = getDocumentRowForVisualRow(visualRowIndex, foldingRanges);
5009
5311
  const relativeX = eventX - x + deltaX;
5010
5312
  const clampedRowIndex = clamp(rowIndex, 0, lines.length - 1);
5011
5313
  const line = lines[clampedRowIndex];
@@ -5225,7 +5527,9 @@ const handleBlur$1 = async editor => {
5225
5527
  }
5226
5528
  const newEditor = {
5227
5529
  ...editor,
5228
- focused: false
5530
+ additionalFocus: 0,
5531
+ focused: false,
5532
+ widgets: closeWidgetsMaybe(editor.widgets || [])
5229
5533
  };
5230
5534
  if (!editor.modified) {
5231
5535
  return newEditor;
@@ -5239,20 +5543,28 @@ const handleBlur$1 = async editor => {
5239
5543
 
5240
5544
  const replaceRange = (editor, ranges, replacement, origin) => {
5241
5545
  const changes = [];
5546
+ const columnDeltas = new Map();
5242
5547
  const rangesLength = ranges.length;
5243
5548
  for (let i = 0; i < rangesLength; i += 4) {
5244
5549
  const [selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn] = getSelectionPairs(ranges, i);
5550
+ const columnDelta = selectionStartRow === selectionEndRow ? columnDeltas.get(selectionStartRow) ?? 0 : 0;
5245
5551
  const start = {
5246
- columnIndex: selectionStartColumn,
5552
+ columnIndex: selectionStartColumn + columnDelta,
5247
5553
  rowIndex: selectionStartRow
5248
5554
  };
5249
5555
  const end = {
5250
- columnIndex: selectionEndColumn,
5556
+ columnIndex: selectionEndColumn + columnDelta,
5251
5557
  rowIndex: selectionEndRow
5252
5558
  };
5253
5559
  const selection = {
5254
- end,
5255
- start
5560
+ end: {
5561
+ columnIndex: selectionEndColumn,
5562
+ rowIndex: selectionEndRow
5563
+ },
5564
+ start: {
5565
+ columnIndex: selectionStartColumn,
5566
+ rowIndex: selectionStartRow
5567
+ }
5256
5568
  };
5257
5569
  changes.push({
5258
5570
  deleted: getSelectionText(editor, selection),
@@ -5261,6 +5573,14 @@ const replaceRange = (editor, ranges, replacement, origin) => {
5261
5573
  origin,
5262
5574
  start: start
5263
5575
  });
5576
+ if (selectionStartRow === selectionEndRow) {
5577
+ if (replacement.length <= 1) {
5578
+ const insertedLength = replacement[0]?.length ?? 0;
5579
+ columnDeltas.set(selectionStartRow, columnDelta + insertedLength - (selectionEndColumn - selectionStartColumn));
5580
+ } else {
5581
+ columnDeltas.set(selectionStartRow, replacement.at(-1).length - selectionEndColumn);
5582
+ }
5583
+ }
5264
5584
  }
5265
5585
  return changes;
5266
5586
  };
@@ -5358,6 +5678,21 @@ const closeCodeGenerator = editor => {
5358
5678
  };
5359
5679
  };
5360
5680
 
5681
+ const closeCompletion = editor => {
5682
+ const {
5683
+ widgets
5684
+ } = editor;
5685
+ if (widgets.every(widget => widget.id !== Completion)) {
5686
+ return editor;
5687
+ }
5688
+ return {
5689
+ ...editor,
5690
+ additionalFocus: 0,
5691
+ focused: true,
5692
+ widgets: removeEditorWidget(widgets, Completion)
5693
+ };
5694
+ };
5695
+
5361
5696
  const isMatchingWidget$1 = widget => {
5362
5697
  return widget.id === Find;
5363
5698
  };
@@ -5372,6 +5707,8 @@ const closeFind = editor => {
5372
5707
  const newWidgets = removeEditorWidget(widgets, Find);
5373
5708
  return {
5374
5709
  ...editor,
5710
+ additionalFocus: 0,
5711
+ focus: FocusEditorText$1,
5375
5712
  focused: true,
5376
5713
  widgets: newWidgets
5377
5714
  };
@@ -5690,6 +6027,10 @@ const copyLineUp = editor => {
5690
6027
  return scheduleDocumentAndCursorsSelections(editor, changes);
5691
6028
  };
5692
6029
 
6030
+ const getLineLength = line => {
6031
+ return line.endsWith('\r') ? line.length - 1 : line.length;
6032
+ };
6033
+
5693
6034
  // @ts-ignore
5694
6035
  const editorGetPositionLeft = (rowIndex, columnIndex, lines, getDelta) => {
5695
6036
  if (columnIndex === 0) {
@@ -5700,7 +6041,7 @@ const editorGetPositionLeft = (rowIndex, columnIndex, lines, getDelta) => {
5700
6041
  };
5701
6042
  }
5702
6043
  return {
5703
- columnIndex: lines[rowIndex - 1].length,
6044
+ columnIndex: getLineLength(lines[rowIndex - 1]),
5704
6045
  rowIndex: rowIndex - 1
5705
6046
  };
5706
6047
  }
@@ -5731,7 +6072,7 @@ const moveToPositionLeft = (selections, i, rowIndex, columnIndex, lines, getDelt
5731
6072
  selections[i + 1] = 0;
5732
6073
  } else {
5733
6074
  selections[i] = rowIndex - 1;
5734
- selections[i + 1] = lines[rowIndex - 1].length;
6075
+ selections[i + 1] = getLineLength(lines[rowIndex - 1]);
5735
6076
  }
5736
6077
  } else {
5737
6078
  const delta = getDelta(lines[rowIndex], columnIndex);
@@ -5818,7 +6159,7 @@ const lineCharacterStart = (line, columnIndex) => {
5818
6159
  return columnIndex;
5819
6160
  };
5820
6161
  const lineEnd = (line, columnIndex) => {
5821
- return line.length - columnIndex;
6162
+ return getLineLength(line) - columnIndex;
5822
6163
  };
5823
6164
  const tryRegexArray = (partialLine, regexArray) => {
5824
6165
  for (const regex of regexArray) {
@@ -5896,7 +6237,7 @@ const editorGetPositionRight = (position, lines, getDelta) => {
5896
6237
  const {
5897
6238
  columnIndex
5898
6239
  } = position;
5899
- if (columnIndex >= lines[rowIndex].length) {
6240
+ if (columnIndex >= getLineLength(lines[rowIndex])) {
5900
6241
  if (rowIndex >= lines.length) {
5901
6242
  return position;
5902
6243
  }
@@ -5916,7 +6257,7 @@ const moveToPositionRight = (selections, i, rowIndex, columnIndex, lines, getDel
5916
6257
  return;
5917
6258
  }
5918
6259
  const line = lines[rowIndex];
5919
- if (columnIndex >= line.length) {
6260
+ if (columnIndex >= getLineLength(line)) {
5920
6261
  selections[i] = selections[i + 2] = rowIndex + 1;
5921
6262
  selections[i + 1] = selections[i + 3] = 0;
5922
6263
  } else {
@@ -5953,6 +6294,28 @@ const cursorCharacterRight = editor => {
5953
6294
  return editorCursorHorizontalRight(editor, characterRight);
5954
6295
  };
5955
6296
 
6297
+ const cursorDocumentEnd = editor => {
6298
+ const {
6299
+ lines,
6300
+ selections
6301
+ } = editor;
6302
+ const rowIndex = lines.length - 1;
6303
+ const columnIndex = lines[rowIndex].length;
6304
+ const newSelections = new Uint32Array(selections.length);
6305
+ for (let i = 0; i < newSelections.length; i += 4) {
6306
+ newSelections[i] = rowIndex;
6307
+ newSelections[i + 1] = columnIndex;
6308
+ newSelections[i + 2] = rowIndex;
6309
+ newSelections[i + 3] = columnIndex;
6310
+ }
6311
+ return scheduleSelections(editor, newSelections);
6312
+ };
6313
+
6314
+ const cursorDocumentStart = editor => {
6315
+ const newSelections = new Uint32Array(editor.selections.length);
6316
+ return scheduleSelections(editor, newSelections);
6317
+ };
6318
+
5956
6319
  const moveSelectionDown = (selections, i, selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) => {
5957
6320
  moveRangeToPosition$1(selections, i, selectionEndRow + 1, selectionEndColumn);
5958
6321
  };
@@ -5977,6 +6340,23 @@ const cursorHome = editor => {
5977
6340
  return editorCursorHorizontalLeft(editor, lineCharacterStart);
5978
6341
  };
5979
6342
 
6343
+ const cursorPageDown = editor => {
6344
+ const {
6345
+ deltaY,
6346
+ itemHeight,
6347
+ lines,
6348
+ numberOfVisibleLines,
6349
+ selections
6350
+ } = editor;
6351
+ const pageSize = Math.max(numberOfVisibleLines, 1);
6352
+ const lastRowIndex = lines.length - 1;
6353
+ const newSelections = map(selections, (result, index, _startRow, _startColumn, endRow, endColumn) => {
6354
+ moveRangeToPosition$1(result, index, Math.min(endRow + pageSize, lastRowIndex), endColumn);
6355
+ });
6356
+ const newEditor = scheduleSelections(editor, newSelections);
6357
+ return setDeltaYFixedValue$1(newEditor, deltaY + pageSize * itemHeight);
6358
+ };
6359
+
5980
6360
  const cursorSet = (editor, rowIndex, columnIndex) => {
5981
6361
  object(editor);
5982
6362
  number(rowIndex);
@@ -6256,6 +6636,93 @@ const deleteCharacterRight = editor => {
6256
6636
  return editorDeleteHorizontalRight(editor, characterRight);
6257
6637
  };
6258
6638
 
6639
+ const getDeleteLineOperations = selections => {
6640
+ const operations = [];
6641
+ for (let i = 0; i < selections.length; i += 4) {
6642
+ const [startRowIndex,, selectionEndRowIndex, endColumnIndex] = getSelectionPairs(selections, i);
6643
+ const endRowIndex = startRowIndex < selectionEndRowIndex && endColumnIndex === 0 ? selectionEndRowIndex - 1 : selectionEndRowIndex;
6644
+ operations.push({
6645
+ endRowIndex,
6646
+ positionColumnIndex: selections[i + 3],
6647
+ startRowIndex
6648
+ });
6649
+ }
6650
+ operations.sort((a, b) => a.startRowIndex - b.startRowIndex || a.endRowIndex - b.endRowIndex);
6651
+ const mergedOperations = [];
6652
+ for (const operation of operations) {
6653
+ const previous = mergedOperations.at(-1);
6654
+ if (previous && previous.endRowIndex + 1 >= operation.startRowIndex) {
6655
+ mergedOperations[mergedOperations.length - 1] = {
6656
+ ...previous,
6657
+ endRowIndex: Math.max(previous.endRowIndex, operation.endRowIndex)
6658
+ };
6659
+ } else {
6660
+ mergedOperations.push(operation);
6661
+ }
6662
+ }
6663
+ return mergedOperations;
6664
+ };
6665
+ const deleteLine$1 = async editor => {
6666
+ const {
6667
+ lines,
6668
+ selections
6669
+ } = editor;
6670
+ if (lines.length === 1 && lines[0] === '') {
6671
+ return editor;
6672
+ }
6673
+ const operations = getDeleteLineOperations(selections);
6674
+ const changes = [];
6675
+ const selectionChanges = new Uint32Array(operations.length * 4);
6676
+ const lastRowIndex = lines.length - 1;
6677
+ let linesDeleted = 0;
6678
+ for (let i = 0; i < operations.length; i++) {
6679
+ const operation = operations[i];
6680
+ let {
6681
+ endRowIndex,
6682
+ startRowIndex
6683
+ } = operation;
6684
+ let startColumnIndex = 0;
6685
+ let endColumnIndex = lines[endRowIndex].length;
6686
+ let survivingLine = '';
6687
+ if (endRowIndex < lastRowIndex) {
6688
+ endRowIndex++;
6689
+ endColumnIndex = 0;
6690
+ survivingLine = lines[endRowIndex];
6691
+ } else if (startRowIndex > 0) {
6692
+ startRowIndex--;
6693
+ startColumnIndex = lines[startRowIndex].length;
6694
+ survivingLine = lines[startRowIndex];
6695
+ }
6696
+ const start = {
6697
+ columnIndex: startColumnIndex,
6698
+ rowIndex: startRowIndex
6699
+ };
6700
+ const end = {
6701
+ columnIndex: endColumnIndex,
6702
+ rowIndex: endRowIndex
6703
+ };
6704
+ changes.push({
6705
+ deleted: getSelectionText(editor, {
6706
+ end,
6707
+ start
6708
+ }),
6709
+ end,
6710
+ inserted: [''],
6711
+ origin: Delete,
6712
+ start
6713
+ });
6714
+ const cursorRowIndex = startRowIndex - linesDeleted;
6715
+ const cursorColumnIndex = Math.min(operation.positionColumnIndex, survivingLine.length);
6716
+ const offset = i * 4;
6717
+ selectionChanges[offset] = cursorRowIndex;
6718
+ selectionChanges[offset + 1] = cursorColumnIndex;
6719
+ selectionChanges[offset + 2] = cursorRowIndex;
6720
+ selectionChanges[offset + 3] = cursorColumnIndex;
6721
+ linesDeleted += operation.endRowIndex - operation.startRowIndex + 1;
6722
+ }
6723
+ return scheduleDocumentAndCursorsSelections(editor, changes, selectionChanges);
6724
+ };
6725
+
6259
6726
  const deleteWordLeft = editor => {
6260
6727
  const newEditor = editorDeleteHorizontalLeft(editor, wordLeft);
6261
6728
  return newEditor;
@@ -6280,6 +6747,38 @@ const findAllReferences$1 = async editor => {
6280
6747
  return editor;
6281
6748
  };
6282
6749
 
6750
+ const fold$1 = editor => {
6751
+ const {
6752
+ foldingRanges = [],
6753
+ lines,
6754
+ primarySelectionIndex = 0,
6755
+ selections
6756
+ } = editor;
6757
+ const rowIndex = selections[primarySelectionIndex];
6758
+ const range = findRange(lines, rowIndex);
6759
+ if (!range) {
6760
+ return editor;
6761
+ }
6762
+ const newRanges = addRange(foldingRanges, range);
6763
+ if (newRanges === foldingRanges) {
6764
+ return editor;
6765
+ }
6766
+ const newSelections = map(selections, (result, index, startRow, startColumn, endRow, endColumn) => {
6767
+ if (startRow >= range.start && endRow <= range.end) {
6768
+ moveRangeToPosition$1(result, index, range.start, Math.min(endColumn, lines[range.start].length));
6769
+ return;
6770
+ }
6771
+ result[index] = startRow;
6772
+ result[index + 1] = startColumn;
6773
+ result[index + 2] = endRow;
6774
+ result[index + 3] = endColumn;
6775
+ });
6776
+ return updateLayout({
6777
+ ...editor,
6778
+ selections: newSelections
6779
+ }, newRanges);
6780
+ };
6781
+
6283
6782
  /* eslint-disable sonarjs/super-linear-regex */
6284
6783
 
6285
6784
  const RE_WORD_START$1 = /^[\w\-]+/;
@@ -6345,6 +6844,7 @@ const i18nString = (key, placeholders = emptyObject) => {
6345
6844
 
6346
6845
  const Copy = 'Copy';
6347
6846
  const Cut = 'Cut';
6847
+ const DeleteLine = 'Delete Line';
6348
6848
  const EditorCloseColorPicker = 'Editor: Close Color Picker';
6349
6849
  const EditorCopyLineDown = 'Editor: Copy Line Down';
6350
6850
  const EditorCopyLineUp = 'Editor: Copy Line Up';
@@ -6366,6 +6866,7 @@ const EnterCode = 'Enter Code';
6366
6866
  const EscapeToClose = 'Escape to close';
6367
6867
  const FindAllImplementations = 'Find All Implementations';
6368
6868
  const FindAllReferences = 'Find All References';
6869
+ const Fold = 'Editor: Fold';
6369
6870
  const FormatDocument = 'Format Document';
6370
6871
  const GoToDefinition = 'Go to Definition';
6371
6872
  const GoToTypeDefinition = 'Go to Type Definition';
@@ -6378,6 +6879,8 @@ const NoTypeDefinitionFoundFor = "No type definition found for '{PH1}'";
6378
6879
  const Paste = 'Paste';
6379
6880
  const SourceAction = 'Source Action';
6380
6881
  const ToggleBlockComment = 'Toggle Block Comment';
6882
+ const ToggleBreakpoint = 'Toggle Breakpoint';
6883
+ const Unfold = 'Editor: Unfold';
6381
6884
 
6382
6885
  const goToDefinition$1 = () => {
6383
6886
  return i18nString(GoToDefinition);
@@ -6413,21 +6916,33 @@ const goToTypeDefinition$1 = () => {
6413
6916
  const findAllReferences = () => {
6414
6917
  return i18nString(FindAllReferences);
6415
6918
  };
6919
+ const fold = () => {
6920
+ return i18nString(Fold);
6921
+ };
6416
6922
  const findAllImplementations = () => {
6417
6923
  return i18nString(FindAllImplementations);
6418
6924
  };
6419
6925
  const cut = () => {
6420
6926
  return i18nString(Cut);
6421
6927
  };
6928
+ const deleteLine = () => {
6929
+ return i18nString(DeleteLine);
6930
+ };
6422
6931
  const copy = () => {
6423
6932
  return i18nString(Copy);
6424
6933
  };
6425
6934
  const paste$1 = () => {
6426
6935
  return i18nString(Paste);
6427
6936
  };
6937
+ const unfold$1 = () => {
6938
+ return i18nString(Unfold);
6939
+ };
6428
6940
  const toggleBlockComment$1 = () => {
6429
6941
  return i18nString(ToggleBlockComment);
6430
6942
  };
6943
+ const toggleBreakpoint$1 = () => {
6944
+ return i18nString(ToggleBreakpoint);
6945
+ };
6431
6946
  const moveLineUp$1 = () => {
6432
6947
  return i18nString(MoveLineUp);
6433
6948
  };
@@ -6624,25 +7139,6 @@ const goToTypeDefinition = async (editor, explicit = true) => {
6624
7139
  });
6625
7140
  };
6626
7141
 
6627
- const isPersistentWidget = widgetId => {
6628
- switch (widgetId) {
6629
- case Find:
6630
- return true;
6631
- default:
6632
- return false;
6633
- }
6634
- };
6635
-
6636
- // TODO widgets should have a persistence property:
6637
- // 1 = close by click (e.g. completion, hover, source-actions)
6638
- // 2 = stay open on click (e.g. find)
6639
- const closeWidgetsMaybe = widgets => {
6640
- if (widgets.length === 0) {
6641
- return widgets;
6642
- }
6643
- return widgets.filter(isPersistentWidget);
6644
- };
6645
-
6646
7142
  const openExternal = async (url, platform) => {
6647
7143
  await openUrl(url, platform);
6648
7144
  };
@@ -6899,7 +7395,30 @@ const handleTripleClick = (editor, modifier, x, y) => {
6899
7395
  };
6900
7396
 
6901
7397
  const PrimaryButton = 0;
7398
+ const SecondaryButton = 2;
7399
+ const isPositionBeforeOrEqual = (rowIndex, columnIndex, otherRowIndex, otherColumnIndex) => {
7400
+ return rowIndex < otherRowIndex || rowIndex === otherRowIndex && columnIndex <= otherColumnIndex;
7401
+ };
7402
+ const isPositionInSelection = (selections, rowIndex, columnIndex) => {
7403
+ for (let i = 0; i < selections.length; i += 4) {
7404
+ const [startRowIndex, startColumnIndex, endRowIndex, endColumnIndex] = getSelectionPairs(selections, i);
7405
+ if (isPositionBeforeOrEqual(startRowIndex, startColumnIndex, rowIndex, columnIndex) && isPositionBeforeOrEqual(rowIndex, columnIndex, endRowIndex, endColumnIndex)) {
7406
+ return true;
7407
+ }
7408
+ }
7409
+ return false;
7410
+ };
7411
+ const handleSecondaryMouseDown = async (state, x, y) => {
7412
+ const position = await at(state, x, y);
7413
+ if (isPositionInSelection(state.selections, position.rowIndex, position.columnIndex)) {
7414
+ return state;
7415
+ }
7416
+ return handleClickAtPosition(state, 0, position.rowIndex, position.columnIndex);
7417
+ };
6902
7418
  const handleMouseDown = async (state, button, altKey, ctrlKey, x, y, detail) => {
7419
+ if (button === SecondaryButton) {
7420
+ return handleSecondaryMouseDown(state, x, y);
7421
+ }
6903
7422
  if (button !== PrimaryButton) {
6904
7423
  return state;
6905
7424
  }
@@ -7146,29 +7665,30 @@ const requestAnimationFrame = fn => {
7146
7665
  };
7147
7666
 
7148
7667
  const shouldUpdateSelectionData = (oldState, newState) => {
7149
- return oldState.selections !== newState.selections || oldState.focused !== newState.focused || oldState.minLineY !== newState.minLineY || oldState.maxLineY !== newState.maxLineY || oldState.differences !== newState.differences || oldState.charWidth !== newState.charWidth || oldState.cursorWidth !== newState.cursorWidth || oldState.fontFamily !== newState.fontFamily || oldState.fontSize !== newState.fontSize || oldState.fontWeight !== newState.fontWeight || oldState.isMonospaceFont !== newState.isMonospaceFont || oldState.letterSpacing !== newState.letterSpacing || oldState.lines !== newState.lines || oldState.rowHeight !== newState.rowHeight || oldState.tabSize !== newState.tabSize || oldState.width !== newState.width;
7668
+ return oldState.selections !== newState.selections || oldState.focused !== newState.focused || oldState.minLineY !== newState.minLineY || oldState.maxLineY !== newState.maxLineY || oldState.foldingRanges !== newState.foldingRanges || oldState.differences !== newState.differences || oldState.charWidth !== newState.charWidth || oldState.cursorWidth !== newState.cursorWidth || oldState.fontFamily !== newState.fontFamily || oldState.fontSize !== newState.fontSize || oldState.fontWeight !== newState.fontWeight || oldState.isMonospaceFont !== newState.isMonospaceFont || oldState.letterSpacing !== newState.letterSpacing || oldState.lines !== newState.lines || oldState.rowHeight !== newState.rowHeight || oldState.tabSize !== newState.tabSize || oldState.width !== newState.width;
7150
7669
  };
7151
7670
  const shouldUpdateVisibleTextData = (oldState, newState) => {
7152
7671
  if (oldState.textInfos !== newState.textInfos || oldState.differences !== newState.differences) {
7153
7672
  return false;
7154
7673
  }
7155
- return oldState.lines !== newState.lines || oldState.tokenizerId !== newState.tokenizerId || oldState.minLineY !== newState.minLineY || oldState.maxLineY !== newState.maxLineY || oldState.decorations !== newState.decorations || oldState.embeds !== newState.embeds || oldState.deltaX !== newState.deltaX || oldState.width !== newState.width || oldState.highlightedLine !== newState.highlightedLine || oldState.debugEnabled !== newState.debugEnabled;
7674
+ return oldState.lines !== newState.lines || oldState.tokenizerId !== newState.tokenizerId || oldState.minLineY !== newState.minLineY || oldState.maxLineY !== newState.maxLineY || oldState.decorations !== newState.decorations || oldState.embeds !== newState.embeds || oldState.deltaX !== newState.deltaX || oldState.width !== newState.width || oldState.highlightedLine !== newState.highlightedLine || oldState.foldingRanges !== newState.foldingRanges || oldState.debugEnabled !== newState.debugEnabled;
7156
7675
  };
7157
7676
  const updateDerivedState = async (oldState, newState) => {
7158
- let finalState = newState;
7159
- if (shouldUpdateVisibleTextData(oldState, newState)) {
7677
+ const nextState = oldState.lines !== newState.lines && 'foldingRanges' in newState ? updateLayout(newState, []) : newState;
7678
+ let finalState = nextState;
7679
+ if (shouldUpdateVisibleTextData(oldState, nextState)) {
7160
7680
  const syncIncremental = getEnabled();
7161
7681
  const {
7162
7682
  differences,
7163
7683
  textInfos
7164
- } = await getVisible$1(newState, syncIncremental);
7684
+ } = await getVisible$1(nextState, syncIncremental);
7165
7685
  finalState = {
7166
- ...newState,
7686
+ ...nextState,
7167
7687
  differences,
7168
7688
  textInfos
7169
7689
  };
7170
7690
  }
7171
- if (!shouldUpdateSelectionData(oldState, newState)) {
7691
+ if (!shouldUpdateSelectionData(oldState, nextState)) {
7172
7692
  return finalState;
7173
7693
  }
7174
7694
  const {
@@ -7863,30 +8383,50 @@ const openCompletion = async editor => {
7863
8383
  return addWidgetToEditor(Completion, EditorCompletion, editor, create$4, newStateGenerator$4, fullFocus);
7864
8384
  };
7865
8385
 
7866
- const create$3 = () => {
7867
- const uid = create$8();
7868
- const widget = {
7869
- id: Find,
7870
- newState: {
7871
- commands: [],
7872
- editorUid: 0,
7873
- height: 0,
7874
- uid,
7875
- width: 0,
7876
- x: 0,
7877
- y: 0
7878
- },
7879
- oldState: {
7880
- commands: [],
7881
- editorUid: 0,
7882
- height: 0,
7883
- uid,
7884
- width: 0,
7885
- x: 0,
7886
- y: 0
7887
- }
7888
- };
7889
- return widget;
8386
+ const isFunctional = widgetId => {
8387
+ switch (widgetId) {
8388
+ case Message:
8389
+ case ColorPicker$1:
8390
+ case Completion:
8391
+ case Find:
8392
+ case Hover:
8393
+ case Rename$1:
8394
+ case SourceAction$1:
8395
+ return true;
8396
+ default:
8397
+ return false;
8398
+ }
8399
+ };
8400
+ const addWidget = (widget, id, render) => {
8401
+ const commands = render(widget);
8402
+ // TODO how to generate a unique integer id
8403
+ // that doesn't collide with ids created in renderer worker?
8404
+ // @ts-ignore
8405
+ const {
8406
+ uid
8407
+ } = widget.newState;
8408
+ const allCommands = [];
8409
+ allCommands.push(['Viewlet.createFunctionalRoot', id, uid, isFunctional(widget.id)]);
8410
+ allCommands.push(...commands);
8411
+ if (isFunctional(widget.id)) {
8412
+ allCommands.push(['Viewlet.appendToBody', uid]);
8413
+ } else {
8414
+ allCommands.push(['Viewlet.send', uid, 'appendWidget']);
8415
+ }
8416
+ const focusCommandIndex = allCommands.findIndex(command => {
8417
+ return command[2] === 'focus' || command[0] === 'Viewlet.focusSelector';
8418
+ });
8419
+ // TODO have separate rendering functions, e.g.
8420
+ // 1. renderDom
8421
+ // 2. renderAriaAnnouncement
8422
+ // 3. renderFocus
8423
+ // to ensure that focus is always after the element is added to the DOM
8424
+ if (focusCommandIndex !== -1) {
8425
+ const command = allCommands[focusCommandIndex];
8426
+ allCommands.splice(focusCommandIndex, 1);
8427
+ allCommands.push(command);
8428
+ }
8429
+ return allCommands;
7890
8430
  };
7891
8431
 
7892
8432
  const launchFindWidgetWorker = async () => {
@@ -7920,22 +8460,330 @@ const dispose = async () => {
7920
8460
  // await rpc.dispose()
7921
8461
  };
7922
8462
 
7923
- const getEditor$1 = editorUid => {
7924
- const instance = get$7(editorUid);
7925
- if (!instance) {
7926
- throw new Error(`editor ${editorUid} not found`);
7927
- }
7928
- const {
7929
- newState
7930
- } = instance;
7931
- return newState;
8463
+ const launchHoverWorker = async () => {
8464
+ const name = 'Hover Worker';
8465
+ const url = 'hoverWorkerMain.js';
8466
+ const intializeCommand = 'Hover.initialize';
8467
+ const rpc = await launchWorker(name, url, intializeCommand);
8468
+ return rpc;
7932
8469
  };
7933
8470
 
7934
- const loadContent$2 = async (state, parentUid) => {
7935
- const {
7936
- uid
7937
- } = state;
7938
- const editor = getEditor$1(parentUid);
8471
+ const state$2 = {};
8472
+ const getOrCreate$1 = () => {
8473
+ if (!state$2.workerPromise) {
8474
+ state$2.workerPromise = launchHoverWorker();
8475
+ }
8476
+ return state$2.workerPromise;
8477
+ };
8478
+ const invoke$2 = async (method, ...params) => {
8479
+ const worker = await getOrCreate$1();
8480
+ return await worker.invoke(method, ...params);
8481
+ };
8482
+
8483
+ const launchSourceActionWorker = async () => {
8484
+ const name = 'Source Action Worker';
8485
+ const url = 'sourceActionWorkerMain.js';
8486
+ const intializeCommand = 'SourceActions.initialize';
8487
+ const rpc = await launchWorker(name, url, intializeCommand);
8488
+ return rpc;
8489
+ };
8490
+
8491
+ const state$1 = {};
8492
+ const getOrCreate = () => {
8493
+ if (!state$1.workerPromise) {
8494
+ state$1.workerPromise = launchSourceActionWorker();
8495
+ }
8496
+ return state$1.workerPromise;
8497
+ };
8498
+ const invoke$1 = async (method, ...params) => {
8499
+ const worker = await getOrCreate();
8500
+ return await worker.invoke(method, ...params);
8501
+ };
8502
+
8503
+ const getWidgetInvoke = widgetId => {
8504
+ switch (widgetId) {
8505
+ case ColorPicker$1:
8506
+ return invoke$9;
8507
+ case Completion:
8508
+ return invoke$4;
8509
+ case Find:
8510
+ return invoke$3;
8511
+ case Hover:
8512
+ return invoke$2;
8513
+ case Rename$1:
8514
+ return invoke$5;
8515
+ case SourceAction$1:
8516
+ return invoke$1;
8517
+ default:
8518
+ return undefined;
8519
+ }
8520
+ };
8521
+
8522
+ const SearchValue = 'search-value';
8523
+ const Close = 'Close';
8524
+
8525
+ const updateWidget = (editor, widgetId, newState) => {
8526
+ // TODO avoid closure
8527
+ const isWidget = widget => {
8528
+ return widget.id === widgetId;
8529
+ };
8530
+ const childIndex = editor.widgets.findIndex(isWidget);
8531
+ if (childIndex === -1) {
8532
+ return editor;
8533
+ }
8534
+ // TODO scroll up/down if necessary
8535
+ const childWidget = editor.widgets[childIndex];
8536
+ const newWidget = {
8537
+ ...childWidget,
8538
+ newState,
8539
+ oldState: childWidget.newState
8540
+ };
8541
+ const newWidgets = [...editor.widgets.slice(0, childIndex), newWidget, ...editor.widgets.slice(childIndex + 1)];
8542
+ return {
8543
+ ...editor,
8544
+ widgets: newWidgets
8545
+ };
8546
+ };
8547
+
8548
+ const getEditorByWidgetUid = (widgetUid, widgetId) => {
8549
+ for (const key of getKeys$2()) {
8550
+ const editor = get$7(Number(key)).newState;
8551
+ const widgets = editor.widgets || [];
8552
+ for (const widget of widgets) {
8553
+ if (widget.id === widgetId && widget.newState.uid === widgetUid) {
8554
+ return editor;
8555
+ }
8556
+ }
8557
+ }
8558
+ return undefined;
8559
+ };
8560
+ const getEditor$1 = (editorOrUid, widgetId) => {
8561
+ if (editorOrUid && editorOrUid.widgets) {
8562
+ return editorOrUid;
8563
+ }
8564
+ const instance = get$7(editorOrUid);
8565
+ if (instance && instance.newState && instance.newState.widgets) {
8566
+ return instance.newState;
8567
+ }
8568
+ return getEditorByWidgetUid(editorOrUid, widgetId);
8569
+ };
8570
+ const createFn = (key, name, widgetId) => {
8571
+ const isWidget = widget => {
8572
+ return widget.id === widgetId;
8573
+ };
8574
+ const isClose = args => {
8575
+ return key === 'close' || key === 'handleClickButton' && args.includes(Close);
8576
+ };
8577
+ const fn = async (editorOrUid, ...args) => {
8578
+ const editor = getEditor$1(editorOrUid, widgetId);
8579
+ if (!editor) {
8580
+ return editorOrUid;
8581
+ }
8582
+ const childIndex = editor.widgets.findIndex(isWidget);
8583
+ if (childIndex === -1) {
8584
+ return editor;
8585
+ }
8586
+ // TODO scroll up/down if necessary
8587
+ const childWidget = editor.widgets[childIndex];
8588
+ const state = childWidget.newState;
8589
+ const {
8590
+ uid
8591
+ } = state;
8592
+ const invoke = getWidgetInvoke(widgetId);
8593
+ await invoke(`${name}.${key}`, uid, ...args);
8594
+ const diff = await invoke(`${name}.diff2`, uid);
8595
+ const commands = await invoke(`${name}.render2`, uid, diff);
8596
+ const latest = get$7(editor.uid).newState;
8597
+ if (isClose(args)) {
8598
+ const newEditor = {
8599
+ ...latest,
8600
+ focused: true,
8601
+ widgets: removeEditorWidget(latest.widgets, widgetId)
8602
+ };
8603
+ set$9(editor.uid, latest, newEditor);
8604
+ return newEditor;
8605
+ }
8606
+ const newState = {
8607
+ ...state,
8608
+ commands
8609
+ };
8610
+ const newEditor = updateWidget(latest, widgetId, newState);
8611
+ set$9(editor.uid, latest, newEditor);
8612
+ return newEditor;
8613
+ };
8614
+ return fn;
8615
+ };
8616
+ const createFns = (keys, name, widgetId) => {
8617
+ const fns = Object.create(null);
8618
+ for (const key of keys) {
8619
+ fns[key] = createFn(key, name, widgetId);
8620
+ }
8621
+ return fns;
8622
+ };
8623
+
8624
+ const renderFull$4 = (oldState, newState) => {
8625
+ const commands = [...newState.commands];
8626
+ // @ts-ignore
8627
+ newState.commands = [];
8628
+ return commands;
8629
+ };
8630
+
8631
+ const AppendToBody = 'Viewlet.appendToBody';
8632
+ const Focus = 'focus';
8633
+ const FocusSelector = 'Viewlet.focusSelector';
8634
+ const RegisterEventListeners = 'Viewlet.registerEventListeners';
8635
+ const SetSelectionByName = 'Viewlet.setSelectionByName';
8636
+ const SetValueByName = 'Viewlet.setValueByName';
8637
+ const SetFocusContext = 'Viewlet.setFocusContext';
8638
+ const SetBounds = 'setBounds';
8639
+ const SetBounds2 = 'Viewlet.setBounds';
8640
+ const SetCss = 'Viewlet.setCss';
8641
+ const SetDom2 = 'Viewlet.setDom2';
8642
+ const SetUid = 'Viewlet.setUid';
8643
+
8644
+ const commandsToForward$5 = [SetDom2, SetCss, AppendToBody, SetBounds2, RegisterEventListeners, SetSelectionByName, SetValueByName, SetFocusContext, SetUid, 'Viewlet.focusSelector'];
8645
+ const render$c = widget => {
8646
+ const commands = renderFull$4(widget.oldState, widget.newState);
8647
+ const wrappedCommands = [];
8648
+ const {
8649
+ uid
8650
+ } = widget.newState;
8651
+ for (const command of commands) {
8652
+ if (commandsToForward$5.includes(command[0])) {
8653
+ wrappedCommands.push(command);
8654
+ } else {
8655
+ wrappedCommands.push(['Viewlet.send', uid, ...command]);
8656
+ }
8657
+ }
8658
+ return wrappedCommands;
8659
+ };
8660
+ const add$8 = widget => {
8661
+ return addWidget(widget, 'FindWidget', render$c);
8662
+ };
8663
+ const remove$7 = widget => {
8664
+ return [['Viewlet.dispose', widget.newState.uid]];
8665
+ };
8666
+ const focusFindInput = editor => {
8667
+ const widget = editor.widgets.find(widget => widget.id === Find);
8668
+ if (!widget) {
8669
+ return editor;
8670
+ }
8671
+ const {
8672
+ uid
8673
+ } = widget.newState;
8674
+ const newState = {
8675
+ ...widget.newState,
8676
+ commands: [[FocusSelector, uid, `[name="${SearchValue}"]`]]
8677
+ };
8678
+ return updateWidget(editor, Find, newState);
8679
+ };
8680
+ const {
8681
+ close: close$4,
8682
+ focusCloseButton,
8683
+ focusFind,
8684
+ focusNext: focusNext$3,
8685
+ focusNextElement,
8686
+ focusNextMatchButton,
8687
+ focusPrevious: focusPrevious$2,
8688
+ focusPreviousElement,
8689
+ focusPreviousMatchButton,
8690
+ focusReplace,
8691
+ focusReplaceAllButton,
8692
+ focusReplaceButton,
8693
+ focusToggleReplace,
8694
+ handleBlur,
8695
+ handleClickButton,
8696
+ handleFocus,
8697
+ handleInput: handleInput$1,
8698
+ handleReplaceFocus,
8699
+ handleReplaceInput,
8700
+ handleToggleReplaceFocus,
8701
+ replace,
8702
+ replaceAll,
8703
+ toggleMatchCase,
8704
+ toggleMatchWholeWord,
8705
+ togglePreserveCase,
8706
+ toggleReplace,
8707
+ toggleUseRegularExpression
8708
+ } = createFns(['close', 'focusCloseButton', 'focusFind', 'focusNext', 'focusNextMatchButton', 'focusPrevious', 'focusPreviousMatchButton', 'focusReplace', 'focusReplaceAllButton', 'focusReplaceButton', 'focusToggleReplace', 'handleBlur', 'handleClickButton', 'handleFocus', 'handleInput', 'handleReplaceFocus', 'handleReplaceInput', 'handleToggleReplaceFocus', 'replace', 'replaceAll', 'toggleMatchCase', 'toggleMatchWholeWord', 'toggleReplace', 'toggleUseRegularExpression', 'focusNextElement', 'focusPreviousElement', 'togglePreserveCase'], 'FindWidget', Find);
8709
+
8710
+ const EditorFindWidget = {
8711
+ __proto__: null,
8712
+ add: add$8,
8713
+ close: close$4,
8714
+ focusCloseButton,
8715
+ focusFind,
8716
+ focusFindInput,
8717
+ focusNext: focusNext$3,
8718
+ focusNextElement,
8719
+ focusNextMatchButton,
8720
+ focusPrevious: focusPrevious$2,
8721
+ focusPreviousElement,
8722
+ focusPreviousMatchButton,
8723
+ focusReplace,
8724
+ focusReplaceAllButton,
8725
+ focusReplaceButton,
8726
+ focusToggleReplace,
8727
+ handleBlur,
8728
+ handleClickButton,
8729
+ handleFocus,
8730
+ handleInput: handleInput$1,
8731
+ handleReplaceFocus,
8732
+ handleReplaceInput,
8733
+ handleToggleReplaceFocus,
8734
+ remove: remove$7,
8735
+ render: render$c,
8736
+ replace,
8737
+ replaceAll,
8738
+ toggleMatchCase,
8739
+ toggleMatchWholeWord,
8740
+ togglePreserveCase,
8741
+ toggleReplace,
8742
+ toggleUseRegularExpression
8743
+ };
8744
+
8745
+ const create$3 = () => {
8746
+ const uid = create$8();
8747
+ const widget = {
8748
+ id: Find,
8749
+ newState: {
8750
+ commands: [],
8751
+ editorUid: 0,
8752
+ height: 0,
8753
+ uid,
8754
+ width: 0,
8755
+ x: 0,
8756
+ y: 0
8757
+ },
8758
+ oldState: {
8759
+ commands: [],
8760
+ editorUid: 0,
8761
+ height: 0,
8762
+ uid,
8763
+ width: 0,
8764
+ x: 0,
8765
+ y: 0
8766
+ }
8767
+ };
8768
+ return widget;
8769
+ };
8770
+
8771
+ const getEditor = editorUid => {
8772
+ const instance = get$7(editorUid);
8773
+ if (!instance) {
8774
+ throw new Error(`editor ${editorUid} not found`);
8775
+ }
8776
+ const {
8777
+ newState
8778
+ } = instance;
8779
+ return newState;
8780
+ };
8781
+
8782
+ const loadContent$2 = async (state, parentUid) => {
8783
+ const {
8784
+ uid
8785
+ } = state;
8786
+ const editor = getEditor(parentUid);
7939
8787
  const {
7940
8788
  height,
7941
8789
  width,
@@ -7957,6 +8805,10 @@ const newStateGenerator$3 = (state, parentUid) => {
7957
8805
  return loadContent$2(state, parentUid);
7958
8806
  };
7959
8807
  const openFind2 = async editor => {
8808
+ const editorWithFocusedFind = focusFindInput(editor);
8809
+ if (editorWithFocusedFind !== editor) {
8810
+ return editorWithFocusedFind;
8811
+ }
7960
8812
  const fullFocus = true;
7961
8813
  return addWidgetToEditor(Find, FindWidget, editor, create$3, newStateGenerator$3, fullFocus);
7962
8814
  };
@@ -8256,7 +9108,7 @@ const getNewSelections$2 = (selections, lines, getDelta) => {
8256
9108
  const line = lines[selectionEndRow];
8257
9109
  newSelections[i] = selectionStartRow;
8258
9110
  newSelections[i + 1] = selectionStartColumn;
8259
- if (selectionEndColumn >= line.length) {
9111
+ if (selectionEndColumn >= getLineLength(line)) {
8260
9112
  newSelections[i + 2] = selectionEndRow + 1;
8261
9113
  newSelections[i + 3] = 0;
8262
9114
  } else {
@@ -8400,9 +9252,7 @@ const selectionGrow = async editor => {
8400
9252
 
8401
9253
  const getSelectionEditsSingleLineWord = (lines, selections) => {
8402
9254
  const lastSelectionIndex = selections.length - 4;
8403
- const rowIndex = selections[lastSelectionIndex];
8404
- const lastSelectionStartColumnIndex = selections[lastSelectionIndex + 1];
8405
- const lastSelectionEndColumnIndex = selections[lastSelectionIndex + 3];
9255
+ const [rowIndex, lastSelectionStartColumnIndex,, lastSelectionEndColumnIndex] = getSelectionPairs(selections, lastSelectionIndex);
8406
9256
  const line = lines[rowIndex];
8407
9257
  const word = line.slice(lastSelectionStartColumnIndex, lastSelectionEndColumnIndex);
8408
9258
  const columnIndexAfter = line.indexOf(word, lastSelectionEndColumnIndex);
@@ -8630,36 +9480,7 @@ const setLanguageId = async (editor, languageId, tokenizePath) => {
8630
9480
  };
8631
9481
 
8632
9482
  const setSelections = (editor, selections) => {
8633
- const {
8634
- maxLineY,
8635
- minLineY,
8636
- rowHeight
8637
- } = editor;
8638
- const startRowIndex = selections[0];
8639
- if (startRowIndex < minLineY) {
8640
- const deltaY = startRowIndex * rowHeight;
8641
- return {
8642
- ...editor,
8643
- deltaY,
8644
- maxLineY: startRowIndex + 1,
8645
- minLineY: startRowIndex,
8646
- selections
8647
- };
8648
- }
8649
- if (startRowIndex > maxLineY) {
8650
- const deltaY = startRowIndex * rowHeight;
8651
- return {
8652
- ...editor,
8653
- deltaY,
8654
- maxLineY: startRowIndex + 1,
8655
- minLineY: startRowIndex,
8656
- selections
8657
- };
8658
- }
8659
- return {
8660
- ...editor,
8661
- selections
8662
- };
9483
+ return scheduleSelections(editor, selections);
8663
9484
  };
8664
9485
 
8665
9486
  const setText = (editor, text) => {
@@ -8721,26 +9542,6 @@ const create$1 = () => {
8721
9542
  return widget;
8722
9543
  };
8723
9544
 
8724
- const launchHoverWorker = async () => {
8725
- const name = 'Hover Worker';
8726
- const url = 'hoverWorkerMain.js';
8727
- const intializeCommand = 'Hover.initialize';
8728
- const rpc = await launchWorker(name, url, intializeCommand);
8729
- return rpc;
8730
- };
8731
-
8732
- const state$2 = {};
8733
- const getOrCreate$1 = () => {
8734
- if (!state$2.workerPromise) {
8735
- state$2.workerPromise = launchHoverWorker();
8736
- }
8737
- return state$2.workerPromise;
8738
- };
8739
- const invoke$2 = async (method, ...params) => {
8740
- const worker = await getOrCreate$1();
8741
- return await worker.invoke(method, ...params);
8742
- };
8743
-
8744
9545
  const newStateGenerator$1 = async (state, parentUid) => {
8745
9546
  const {
8746
9547
  height,
@@ -8805,26 +9606,6 @@ const create = () => {
8805
9606
  return widget;
8806
9607
  };
8807
9608
 
8808
- const launchSourceActionWorker = async () => {
8809
- const name = 'Source Action Worker';
8810
- const url = 'sourceActionWorkerMain.js';
8811
- const intializeCommand = 'SourceActions.initialize';
8812
- const rpc = await launchWorker(name, url, intializeCommand);
8813
- return rpc;
8814
- };
8815
-
8816
- const state$1 = {};
8817
- const getOrCreate = () => {
8818
- if (!state$1.workerPromise) {
8819
- state$1.workerPromise = launchSourceActionWorker();
8820
- }
8821
- return state$1.workerPromise;
8822
- };
8823
- const invoke$1 = async (method, ...params) => {
8824
- const worker = await getOrCreate();
8825
- return await worker.invoke(method, ...params);
8826
- };
8827
-
8828
9609
  const newStateGenerator = async (state, parentUid) => {
8829
9610
  const {
8830
9611
  height,
@@ -9080,7 +9861,7 @@ const createDeleteEdit = (rowIndex, columnIndex, text) => {
9080
9861
  columnIndex: columnIndex + text.length,
9081
9862
  rowIndex
9082
9863
  },
9083
- inserted: [],
9864
+ inserted: [''],
9084
9865
  origin: ToggleBlockComment$1,
9085
9866
  start: {
9086
9867
  columnIndex,
@@ -9151,7 +9932,7 @@ const getBlockCommentEdits = (editor, blockComment) => {
9151
9932
  endColumnIndex -= whitespaceAtEnd[0].length;
9152
9933
  }
9153
9934
  const change1 = {
9154
- deleted: [],
9935
+ deleted: [''],
9155
9936
  end: {
9156
9937
  columnIndex: startColumnIndex,
9157
9938
  rowIndex
@@ -9164,7 +9945,7 @@ const getBlockCommentEdits = (editor, blockComment) => {
9164
9945
  }
9165
9946
  };
9166
9947
  const change2 = {
9167
- deleted: [],
9948
+ deleted: [''],
9168
9949
  end: {
9169
9950
  columnIndex: endColumnIndex + blockCommentStart.length,
9170
9951
  rowIndex
@@ -9232,6 +10013,15 @@ const toggleBlockComment = async editor => {
9232
10013
  return scheduleDocument(editor, edits);
9233
10014
  };
9234
10015
 
10016
+ const toggleBreakpoint = editor => {
10017
+ const [rowIndex] = editor.selections;
10018
+ const breakPoints = editor.breakPoints.includes(rowIndex) ? editor.breakPoints.filter(breakPoint => breakPoint !== rowIndex) : [...editor.breakPoints, rowIndex];
10019
+ return {
10020
+ ...editor,
10021
+ breakPoints
10022
+ };
10023
+ };
10024
+
9235
10025
  const getLineComment = async editor => {
9236
10026
  const languageConfiguration = await getLanguageConfiguration(editor);
9237
10027
  if (!languageConfiguration?.comments?.lineComment) {
@@ -9507,6 +10297,20 @@ const undo = state => {
9507
10297
  return scheduleDocumentAndCursorsSelectionIsUndo(newState, inverseChanges);
9508
10298
  };
9509
10299
 
10300
+ const unfold = editor => {
10301
+ const {
10302
+ foldingRanges = [],
10303
+ primarySelectionIndex = 0,
10304
+ selections
10305
+ } = editor;
10306
+ const rowIndex = selections[primarySelectionIndex];
10307
+ const newRanges = removeRangeAt(foldingRanges, rowIndex);
10308
+ if (newRanges === foldingRanges) {
10309
+ return editor;
10310
+ }
10311
+ return updateLayout(editor, newRanges);
10312
+ };
10313
+
9510
10314
  // @ts-ignore
9511
10315
 
9512
10316
  // const INDENT = ' '
@@ -9546,282 +10350,103 @@ const editorUnindent = editor => {
9546
10350
  // }
9547
10351
  // let previousRowIndex = -1
9548
10352
  // for (const selection of editor.selections) {
9549
- // let startRowIndex = selection.start.rowIndex
9550
- // const endRowIndex = selection.end.rowIndex
9551
- // if (startRowIndex === previousRowIndex) {
9552
- // startRowIndex++
9553
- // }
9554
- // for (let i = startRowIndex; i <= endRowIndex; i++) {
9555
- // indentLineMaybe(i)
9556
- // }
9557
- // let start = selection.start
9558
- // let end = selection.end
9559
- // if (editor.lines[start.rowIndex].startsWith(INDENT)) {
9560
- // start = {
9561
- // rowIndex: start.rowIndex,
9562
- // columnIndex: Math.max(start.columnIndex - INDENT.length, 0),
9563
- // }
9564
- // }
9565
- // if (editor.lines[end.rowIndex].startsWith(INDENT)) {
9566
- // end = {
9567
- // rowIndex: end.rowIndex,
9568
- // columnIndex: Math.max(end.columnIndex - INDENT.length, 0),
9569
- // }
9570
- // }
9571
- // cursorEdits.push(end)
9572
- // selectionEdits.push({
9573
- // start,
9574
- // end,
9575
- // })
9576
- // previousRowIndex = endRowIndex
9577
- // }
9578
- // // @ts-ignore
9579
- // Editor.scheduleDocumentAndCursorsAndSelections(editor, documentEdits, cursorEdits, selectionEdits)
9580
- // return
9581
- // }
9582
- // const documentEdits = []
9583
- // const cursorEdits = []
9584
- // if (!editor.lines[editor.cursor.rowIndex].startsWith(INDENT)) {
9585
- // return
9586
- // }
9587
- // // @ts-ignore
9588
- // documentEdits.push({
9589
- // type: /* singleLineEdit */ 1,
9590
- // rowIndex: editor.cursor.rowIndex,
9591
- // inserted: '',
9592
- // columnIndex: 2,
9593
- // deleted: 2,
9594
- // })
9595
- // // @ts-ignore
9596
- // cursorEdits.push({
9597
- // rowIndex: editor.cursor.rowIndex,
9598
- // columnIndex: editor.cursor.columnIndex - 2,
9599
- // })
9600
- // // @ts-ignore
9601
- // Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
9602
- return editor;
9603
- };
9604
- // const editor = {
9605
- // textDocument: {
9606
- // lines: [' line 1'],
9607
- // },
9608
- // cursor: {
9609
- // rowIndex: 0,
9610
- // columnIndex: 8,
9611
- // },
9612
- // selections: [
9613
- // {
9614
- // start: {
9615
- // rowIndex: 0,
9616
- // columnIndex: 0,
9617
- // },
9618
- // end: {
9619
- // rowIndex: 0,
9620
- // columnIndex: 8,
9621
- // },
9622
- // },
9623
- // ],
9624
- // tokenizer: TokenizePlainText,
9625
- // }
9626
- // editorUnindent(editor)
9627
-
9628
- // editor.lines //?
9629
-
9630
- const isFunctional = widgetId => {
9631
- switch (widgetId) {
9632
- case Message:
9633
- case ColorPicker$1:
9634
- case Completion:
9635
- case Find:
9636
- case Hover:
9637
- case Rename$1:
9638
- case SourceAction$1:
9639
- return true;
9640
- default:
9641
- return false;
9642
- }
9643
- };
9644
- const addWidget = (widget, id, render) => {
9645
- const commands = render(widget);
9646
- // TODO how to generate a unique integer id
9647
- // that doesn't collide with ids created in renderer worker?
9648
- // @ts-ignore
9649
- const {
9650
- uid
9651
- } = widget.newState;
9652
- const allCommands = [];
9653
- allCommands.push(['Viewlet.createFunctionalRoot', id, uid, isFunctional(widget.id)]);
9654
- allCommands.push(...commands);
9655
- if (isFunctional(widget.id)) {
9656
- allCommands.push(['Viewlet.appendToBody', uid]);
9657
- } else {
9658
- allCommands.push(['Viewlet.send', uid, 'appendWidget']);
9659
- }
9660
- const focusCommandIndex = allCommands.findIndex(command => {
9661
- return command[2] === 'focus' || command[0] === 'Viewlet.focusSelector';
9662
- });
9663
- // TODO have separate rendering functions, e.g.
9664
- // 1. renderDom
9665
- // 2. renderAriaAnnouncement
9666
- // 3. renderFocus
9667
- // to ensure that focus is always after the element is added to the DOM
9668
- if (focusCommandIndex !== -1) {
9669
- const command = allCommands[focusCommandIndex];
9670
- allCommands.splice(focusCommandIndex, 1);
9671
- allCommands.push(command);
9672
- }
9673
- return allCommands;
9674
- };
9675
-
9676
- const getWidgetInvoke = widgetId => {
9677
- switch (widgetId) {
9678
- case ColorPicker$1:
9679
- return invoke$9;
9680
- case Completion:
9681
- return invoke$4;
9682
- case Find:
9683
- return invoke$3;
9684
- case Hover:
9685
- return invoke$2;
9686
- case Rename$1:
9687
- return invoke$5;
9688
- case SourceAction$1:
9689
- return invoke$1;
9690
- default:
9691
- return undefined;
9692
- }
9693
- };
9694
-
9695
- const Close = 'Close';
9696
-
9697
- const updateWidget = (editor, widgetId, newState) => {
9698
- // TODO avoid closure
9699
- const isWidget = widget => {
9700
- return widget.id === widgetId;
9701
- };
9702
- const childIndex = editor.widgets.findIndex(isWidget);
9703
- if (childIndex === -1) {
9704
- return editor;
9705
- }
9706
- // TODO scroll up/down if necessary
9707
- const childWidget = editor.widgets[childIndex];
9708
- const newWidget = {
9709
- ...childWidget,
9710
- newState,
9711
- oldState: childWidget.newState
9712
- };
9713
- const newWidgets = [...editor.widgets.slice(0, childIndex), newWidget, ...editor.widgets.slice(childIndex + 1)];
9714
- return {
9715
- ...editor,
9716
- widgets: newWidgets
9717
- };
9718
- };
9719
-
9720
- const getEditorByWidgetUid = (widgetUid, widgetId) => {
9721
- for (const key of getKeys$2()) {
9722
- const editor = get$7(Number(key)).newState;
9723
- const widgets = editor.widgets || [];
9724
- for (const widget of widgets) {
9725
- if (widget.id === widgetId && widget.newState.uid === widgetUid) {
9726
- return editor;
9727
- }
9728
- }
9729
- }
9730
- return undefined;
9731
- };
9732
- const getEditor = (editorOrUid, widgetId) => {
9733
- if (editorOrUid && editorOrUid.widgets) {
9734
- return editorOrUid;
9735
- }
9736
- const instance = get$7(editorOrUid);
9737
- if (instance && instance.newState && instance.newState.widgets) {
9738
- return instance.newState;
9739
- }
9740
- return getEditorByWidgetUid(editorOrUid, widgetId);
9741
- };
9742
- const createFn = (key, name, widgetId) => {
9743
- const isWidget = widget => {
9744
- return widget.id === widgetId;
9745
- };
9746
- const isClose = args => {
9747
- return key === 'close' || key === 'handleClickButton' && args.includes(Close);
9748
- };
9749
- const fn = async (editorOrUid, ...args) => {
9750
- const editor = getEditor(editorOrUid, widgetId);
9751
- if (!editor) {
9752
- return editorOrUid;
9753
- }
9754
- const childIndex = editor.widgets.findIndex(isWidget);
9755
- if (childIndex === -1) {
9756
- return editor;
9757
- }
9758
- // TODO scroll up/down if necessary
9759
- const childWidget = editor.widgets[childIndex];
9760
- const state = childWidget.newState;
9761
- const {
9762
- uid
9763
- } = state;
9764
- const invoke = getWidgetInvoke(widgetId);
9765
- await invoke(`${name}.${key}`, uid, ...args);
9766
- const diff = await invoke(`${name}.diff2`, uid);
9767
- const commands = await invoke(`${name}.render2`, uid, diff);
9768
- const latest = get$7(editor.uid).newState;
9769
- if (isClose(args)) {
9770
- const newEditor = {
9771
- ...latest,
9772
- focused: true,
9773
- widgets: removeEditorWidget(latest.widgets, widgetId)
9774
- };
9775
- set$9(editor.uid, latest, newEditor);
9776
- return newEditor;
9777
- }
9778
- const newState = {
9779
- ...state,
9780
- commands
9781
- };
9782
- const newEditor = updateWidget(latest, widgetId, newState);
9783
- set$9(editor.uid, latest, newEditor);
9784
- return newEditor;
9785
- };
9786
- return fn;
9787
- };
9788
- const createFns = (keys, name, widgetId) => {
9789
- const fns = Object.create(null);
9790
- for (const key of keys) {
9791
- fns[key] = createFn(key, name, widgetId);
9792
- }
9793
- return fns;
10353
+ // let startRowIndex = selection.start.rowIndex
10354
+ // const endRowIndex = selection.end.rowIndex
10355
+ // if (startRowIndex === previousRowIndex) {
10356
+ // startRowIndex++
10357
+ // }
10358
+ // for (let i = startRowIndex; i <= endRowIndex; i++) {
10359
+ // indentLineMaybe(i)
10360
+ // }
10361
+ // let start = selection.start
10362
+ // let end = selection.end
10363
+ // if (editor.lines[start.rowIndex].startsWith(INDENT)) {
10364
+ // start = {
10365
+ // rowIndex: start.rowIndex,
10366
+ // columnIndex: Math.max(start.columnIndex - INDENT.length, 0),
10367
+ // }
10368
+ // }
10369
+ // if (editor.lines[end.rowIndex].startsWith(INDENT)) {
10370
+ // end = {
10371
+ // rowIndex: end.rowIndex,
10372
+ // columnIndex: Math.max(end.columnIndex - INDENT.length, 0),
10373
+ // }
10374
+ // }
10375
+ // cursorEdits.push(end)
10376
+ // selectionEdits.push({
10377
+ // start,
10378
+ // end,
10379
+ // })
10380
+ // previousRowIndex = endRowIndex
10381
+ // }
10382
+ // // @ts-ignore
10383
+ // Editor.scheduleDocumentAndCursorsAndSelections(editor, documentEdits, cursorEdits, selectionEdits)
10384
+ // return
10385
+ // }
10386
+ // const documentEdits = []
10387
+ // const cursorEdits = []
10388
+ // if (!editor.lines[editor.cursor.rowIndex].startsWith(INDENT)) {
10389
+ // return
10390
+ // }
10391
+ // // @ts-ignore
10392
+ // documentEdits.push({
10393
+ // type: /* singleLineEdit */ 1,
10394
+ // rowIndex: editor.cursor.rowIndex,
10395
+ // inserted: '',
10396
+ // columnIndex: 2,
10397
+ // deleted: 2,
10398
+ // })
10399
+ // // @ts-ignore
10400
+ // cursorEdits.push({
10401
+ // rowIndex: editor.cursor.rowIndex,
10402
+ // columnIndex: editor.cursor.columnIndex - 2,
10403
+ // })
10404
+ // // @ts-ignore
10405
+ // Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
10406
+ return editor;
9794
10407
  };
10408
+ // const editor = {
10409
+ // textDocument: {
10410
+ // lines: [' line 1'],
10411
+ // },
10412
+ // cursor: {
10413
+ // rowIndex: 0,
10414
+ // columnIndex: 8,
10415
+ // },
10416
+ // selections: [
10417
+ // {
10418
+ // start: {
10419
+ // rowIndex: 0,
10420
+ // columnIndex: 0,
10421
+ // },
10422
+ // end: {
10423
+ // rowIndex: 0,
10424
+ // columnIndex: 8,
10425
+ // },
10426
+ // },
10427
+ // ],
10428
+ // tokenizer: TokenizePlainText,
10429
+ // }
10430
+ // editorUnindent(editor)
9795
10431
 
9796
- const AppendToBody = 'Viewlet.appendToBody';
9797
- const Focus = 'focus';
9798
- const FocusSelector = 'Viewlet.focusSelector';
9799
- const RegisterEventListeners = 'Viewlet.registerEventListeners';
9800
- const SetSelectionByName = 'Viewlet.setSelectionByName';
9801
- const SetValueByName = 'Viewlet.setValueByName';
9802
- const SetFocusContext = 'Viewlet.setFocusContext';
9803
- const SetBounds = 'setBounds';
9804
- const SetBounds2 = 'Viewlet.setBounds';
9805
- const SetCss = 'Viewlet.setCss';
9806
- const SetDom2 = 'Viewlet.setDom2';
9807
- const SetUid = 'Viewlet.setUid';
10432
+ // editor.lines //?
9808
10433
 
9809
- const renderFull$4 = (oldState, newState) => {
10434
+ const renderFull$3 = (oldState, newState) => {
9810
10435
  const commands = [...newState.commands];
9811
10436
  // @ts-ignore
9812
10437
  newState.commands = [];
9813
10438
  return commands;
9814
10439
  };
9815
10440
 
9816
- const commandsToForward$5 = [SetDom2, SetCss, AppendToBody, SetBounds2, RegisterEventListeners, SetSelectionByName, SetValueByName, SetFocusContext, SetUid, 'Viewlet.focusSelector'];
9817
- const render$c = widget => {
9818
- const commands = renderFull$4(widget.oldState, widget.newState);
10441
+ const commandsToForward$4 = [SetDom2, SetCss, AppendToBody, SetBounds2, RegisterEventListeners, SetSelectionByName, SetValueByName, SetFocusContext, SetUid, 'Viewlet.focusSelector'];
10442
+ const render$b = widget => {
10443
+ const commands = renderFull$3(widget.oldState, widget.newState);
9819
10444
  const wrappedCommands = [];
9820
10445
  const {
9821
10446
  uid
9822
10447
  } = widget.newState;
9823
10448
  for (const command of commands) {
9824
- if (commandsToForward$5.includes(command[0])) {
10449
+ if (commandsToForward$4.includes(command[0])) {
9825
10450
  wrappedCommands.push(command);
9826
10451
  } else {
9827
10452
  wrappedCommands.push(['Viewlet.send', uid, ...command]);
@@ -9829,20 +10454,20 @@ const render$c = widget => {
9829
10454
  }
9830
10455
  return wrappedCommands;
9831
10456
  };
9832
- const add$8 = widget => {
9833
- return addWidget(widget, 'EditorCompletion', render$c);
10457
+ const add$7 = widget => {
10458
+ return addWidget(widget, 'EditorCompletion', render$b);
9834
10459
  };
9835
- const remove$7 = widget => {
10460
+ const remove$6 = widget => {
9836
10461
  return [['Viewlet.dispose', widget.newState.uid]];
9837
10462
  };
9838
10463
  const {
9839
- close: close$4,
10464
+ close: close$3,
9840
10465
  closeDetails: closeDetails$1,
9841
10466
  focusFirst: focusFirst$1,
9842
10467
  focusIndex: focusIndex$2,
9843
10468
  focusLast: focusLast$1,
9844
- focusNext: focusNext$3,
9845
- focusPrevious: focusPrevious$2,
10469
+ focusNext: focusNext$2,
10470
+ focusPrevious: focusPrevious$1,
9846
10471
  handleEditorBlur,
9847
10472
  handleEditorClick,
9848
10473
  handleEditorDeleteLeft: handleEditorDeleteLeft$1,
@@ -9857,14 +10482,14 @@ const {
9857
10482
 
9858
10483
  const EditorCompletionWidget = {
9859
10484
  __proto__: null,
9860
- add: add$8,
9861
- close: close$4,
10485
+ add: add$7,
10486
+ close: close$3,
9862
10487
  closeDetails: closeDetails$1,
9863
10488
  focusFirst: focusFirst$1,
9864
10489
  focusIndex: focusIndex$2,
9865
10490
  focusLast: focusLast$1,
9866
- focusNext: focusNext$3,
9867
- focusPrevious: focusPrevious$2,
10491
+ focusNext: focusNext$2,
10492
+ focusPrevious: focusPrevious$1,
9868
10493
  handleEditorBlur,
9869
10494
  handleEditorClick,
9870
10495
  handleEditorDeleteLeft: handleEditorDeleteLeft$1,
@@ -9872,106 +10497,13 @@ const EditorCompletionWidget = {
9872
10497
  handlePointerDown,
9873
10498
  handleWheel: handleWheel$1,
9874
10499
  openDetails,
9875
- remove: remove$7,
9876
- render: render$c,
10500
+ remove: remove$6,
10501
+ render: render$b,
9877
10502
  selectCurrent: selectCurrent$1,
9878
10503
  selectIndex: selectIndex$1,
9879
10504
  toggleDetails: toggleDetails$1
9880
10505
  };
9881
10506
 
9882
- const renderFull$3 = (oldState, newState) => {
9883
- const commands = [...newState.commands];
9884
- // @ts-ignore
9885
- newState.commands = [];
9886
- return commands;
9887
- };
9888
-
9889
- const commandsToForward$4 = [SetDom2, SetCss, AppendToBody, SetBounds2, RegisterEventListeners, SetSelectionByName, SetValueByName, SetFocusContext, SetUid, 'Viewlet.focusSelector'];
9890
- const render$b = widget => {
9891
- const commands = renderFull$3(widget.oldState, widget.newState);
9892
- const wrappedCommands = [];
9893
- const {
9894
- uid
9895
- } = widget.newState;
9896
- for (const command of commands) {
9897
- if (commandsToForward$4.includes(command[0])) {
9898
- wrappedCommands.push(command);
9899
- } else {
9900
- wrappedCommands.push(['Viewlet.send', uid, ...command]);
9901
- }
9902
- }
9903
- return wrappedCommands;
9904
- };
9905
- const add$7 = widget => {
9906
- return addWidget(widget, 'FindWidget', render$b);
9907
- };
9908
- const remove$6 = widget => {
9909
- return [['Viewlet.dispose', widget.newState.uid]];
9910
- };
9911
- const {
9912
- close: close$3,
9913
- focusCloseButton,
9914
- focusFind,
9915
- focusNext: focusNext$2,
9916
- focusNextElement,
9917
- focusNextMatchButton,
9918
- focusPrevious: focusPrevious$1,
9919
- focusPreviousElement,
9920
- focusPreviousMatchButton,
9921
- focusReplace,
9922
- focusReplaceAllButton,
9923
- focusReplaceButton,
9924
- focusToggleReplace,
9925
- handleBlur,
9926
- handleClickButton,
9927
- handleFocus,
9928
- handleInput: handleInput$1,
9929
- handleReplaceFocus,
9930
- handleReplaceInput,
9931
- handleToggleReplaceFocus,
9932
- replace,
9933
- replaceAll,
9934
- toggleMatchCase,
9935
- toggleMatchWholeWord,
9936
- togglePreserveCase,
9937
- toggleReplace,
9938
- toggleUseRegularExpression
9939
- } = createFns(['close', 'focusCloseButton', 'focusFind', 'focusNext', 'focusNextMatchButton', 'focusPrevious', 'focusPreviousMatchButton', 'focusReplace', 'focusReplaceAllButton', 'focusReplaceButton', 'focusToggleReplace', 'handleBlur', 'handleClickButton', 'handleFocus', 'handleInput', 'handleReplaceFocus', 'handleReplaceInput', 'handleToggleReplaceFocus', 'replace', 'replaceAll', 'toggleMatchCase', 'toggleMatchWholeWord', 'toggleReplace', 'toggleUseRegularExpression', 'focusNextElement', 'focusPreviousElement', 'togglePreserveCase'], 'FindWidget', Find);
9940
-
9941
- const EditorFindWidget = {
9942
- __proto__: null,
9943
- add: add$7,
9944
- close: close$3,
9945
- focusCloseButton,
9946
- focusFind,
9947
- focusNext: focusNext$2,
9948
- focusNextElement,
9949
- focusNextMatchButton,
9950
- focusPrevious: focusPrevious$1,
9951
- focusPreviousElement,
9952
- focusPreviousMatchButton,
9953
- focusReplace,
9954
- focusReplaceAllButton,
9955
- focusReplaceButton,
9956
- focusToggleReplace,
9957
- handleBlur,
9958
- handleClickButton,
9959
- handleFocus,
9960
- handleInput: handleInput$1,
9961
- handleReplaceFocus,
9962
- handleReplaceInput,
9963
- handleToggleReplaceFocus,
9964
- remove: remove$6,
9965
- render: render$b,
9966
- replace,
9967
- replaceAll,
9968
- toggleMatchCase,
9969
- toggleMatchWholeWord,
9970
- togglePreserveCase,
9971
- toggleReplace,
9972
- toggleUseRegularExpression
9973
- };
9974
-
9975
10507
  const getTextDocument = editor => {
9976
10508
  return {
9977
10509
  documentId: editor.id || editor.uid,
@@ -10346,7 +10878,7 @@ const renderHover = (oldState, newState) => {
10346
10878
 
10347
10879
  const commandsToForward$3 = [SetDom2, SetCss, AppendToBody, SetBounds2, RegisterEventListeners, SetSelectionByName, SetValueByName, SetFocusContext, SetUid, 'Viewlet.focusSelector'];
10348
10880
  const render$9 = widget => {
10349
- const commands = renderFull$4(widget.oldState, widget.newState);
10881
+ const commands = renderFull$3(widget.oldState, widget.newState);
10350
10882
  const wrappedCommands = [];
10351
10883
  const {
10352
10884
  uid
@@ -10407,7 +10939,7 @@ const removeWidget = widget => {
10407
10939
 
10408
10940
  const commandsToForward$2 = [SetDom2, SetCss, AppendToBody, SetBounds2, RegisterEventListeners, SetSelectionByName, SetValueByName, SetFocusContext, SetUid, 'Viewlet.focusSelector'];
10409
10941
  const render$8 = widget => {
10410
- const commands = renderFull$4(widget.oldState, widget.newState);
10942
+ const commands = renderFull$3(widget.oldState, widget.newState);
10411
10943
  const wrappedCommands = [];
10412
10944
  const {
10413
10945
  uid
@@ -10474,7 +11006,7 @@ const executeWidgetCommand = async (editor, name, method, _uid, widgetId, ...par
10474
11006
  const isWidget = widget => {
10475
11007
  return widget.id === widgetId;
10476
11008
  };
10477
- const latestEditor = getEditor$1(editor.uid);
11009
+ const latestEditor = getEditor(editor.uid);
10478
11010
  const childIndex1 = latestEditor.widgets.findIndex(isWidget);
10479
11011
  if (childIndex1 === -1) {
10480
11012
  return latestEditor;
@@ -10555,54 +11087,54 @@ const FocusEditorCodeGenerator = 52;
10555
11087
  const FocusColorPicker = 41;
10556
11088
 
10557
11089
  const getPositionAtCursor = editorUid => {
10558
- const editor = getEditor$1(editorUid);
11090
+ const editor = getEditor(editorUid);
10559
11091
  return getPositionAtCursor$1(editor);
10560
11092
  };
10561
11093
  const getUri = editorUid => {
10562
- const editor = getEditor$1(editorUid);
11094
+ const editor = getEditor(editorUid);
10563
11095
  return editor.uri;
10564
11096
  };
10565
11097
  const getLanguageId = editorUid => {
10566
- const editor = getEditor$1(editorUid);
11098
+ const editor = getEditor(editorUid);
10567
11099
  return editor.languageId;
10568
11100
  };
10569
11101
  const getOffsetAtCursor = editorUid => {
10570
- const editor = getEditor$1(editorUid);
11102
+ const editor = getEditor(editorUid);
10571
11103
  return getOffsetAtCursor$1(editor);
10572
11104
  };
10573
11105
  const getWordAt = (editorUid, rowIndex, columnIndex) => {
10574
- const editor = getEditor$1(editorUid);
11106
+ const editor = getEditor(editorUid);
10575
11107
  const {
10576
11108
  word
10577
11109
  } = getWordAt$1(editor, rowIndex, columnIndex);
10578
11110
  return word;
10579
11111
  };
10580
11112
  const getWordAtOffset2 = editorUid => {
10581
- const editor = getEditor$1(editorUid);
11113
+ const editor = getEditor(editorUid);
10582
11114
  const word = getWordAtOffset(editor);
10583
11115
  return word;
10584
11116
  };
10585
11117
  const getWordBefore2 = (editorUid, rowIndex, columnIndex) => {
10586
- const editor = getEditor$1(editorUid);
11118
+ const editor = getEditor(editorUid);
10587
11119
  const word = getWordBefore(editor, rowIndex, columnIndex);
10588
11120
  return word;
10589
11121
  };
10590
11122
  const getLines2 = editorUid => {
10591
- const editor = getEditor$1(editorUid);
11123
+ const editor = getEditor(editorUid);
10592
11124
  const {
10593
11125
  lines
10594
11126
  } = editor;
10595
11127
  return lines;
10596
11128
  };
10597
11129
  const getSelections2 = editorUid => {
10598
- const editor = getEditor$1(editorUid);
11130
+ const editor = getEditor(editorUid);
10599
11131
  const {
10600
11132
  selections
10601
11133
  } = editor;
10602
11134
  return selections;
10603
11135
  };
10604
11136
  const setSelections2 = async (editorUid, selections) => {
10605
- const editor = getEditor$1(editorUid);
11137
+ const editor = getEditor(editorUid);
10606
11138
  const newEditor = {
10607
11139
  ...editor,
10608
11140
  selections
@@ -10611,7 +11143,7 @@ const setSelections2 = async (editorUid, selections) => {
10611
11143
  set$9(editorUid, editor, newEditorWithDerivedState);
10612
11144
  };
10613
11145
  const closeWidget2 = async (editorUid, widgetId, widgetName, unsetAdditionalFocus$1) => {
10614
- const editor = getEditor$1(editorUid);
11146
+ const editor = getEditor(editorUid);
10615
11147
  const invoke = getWidgetInvoke(widgetId);
10616
11148
  const {
10617
11149
  widgets
@@ -10639,7 +11171,7 @@ const closeFind2 = async editorUid => {
10639
11171
  await closeWidget2(editorUid, Find, 'FindWidget', 0);
10640
11172
  };
10641
11173
  const applyEdits2 = async (editorUid, edits) => {
10642
- const editor = getEditor$1(editorUid);
11174
+ const editor = getEditor(editorUid);
10643
11175
  const newEditor = await applyEdit(editor, edits);
10644
11176
  const newEditorWithDerivedState = await updateDerivedState(editor, newEditor);
10645
11177
  set$9(editorUid, editor, newEditorWithDerivedState);
@@ -10649,7 +11181,7 @@ const getSourceActions = async editorUid => {
10649
11181
  return actions;
10650
11182
  };
10651
11183
  const getDiagnostics$1 = async editorUid => {
10652
- const editor = getEditor$1(editorUid);
11184
+ const editor = getEditor(editorUid);
10653
11185
  const {
10654
11186
  diagnostics
10655
11187
  } = editor;
@@ -10693,6 +11225,10 @@ const getKeyBindings = () => {
10693
11225
  command: 'FindWidget.focusNext',
10694
11226
  key: Enter,
10695
11227
  when: FocusFindWidget
11228
+ }, {
11229
+ command: 'FindWidget.focusPrevious',
11230
+ key: Shift | Enter,
11231
+ when: FocusFindWidget
10696
11232
  }, {
10697
11233
  command: 'FindWidget.preventDefaultBrowserFind',
10698
11234
  key: CtrlCmd | KeyF,
@@ -10774,7 +11310,7 @@ const getKeyBindings = () => {
10774
11310
  key: Enter,
10775
11311
  when: FocusEditorCompletions
10776
11312
  }, {
10777
- command: 'EditorCompletion.close',
11313
+ command: 'Editor.closeCompletion',
10778
11314
  key: Escape,
10779
11315
  when: FocusEditorCompletions
10780
11316
  }, {
@@ -10797,6 +11333,14 @@ const getKeyBindings = () => {
10797
11333
  command: 'Editor.cursorWordLeft',
10798
11334
  key: CtrlCmd | LeftArrow,
10799
11335
  when: FocusEditorText
11336
+ }, {
11337
+ command: 'Editor.cursorDocumentEnd',
11338
+ key: CtrlCmd | End,
11339
+ when: FocusEditorText
11340
+ }, {
11341
+ command: 'Editor.cursorDocumentStart',
11342
+ key: CtrlCmd | Home,
11343
+ when: FocusEditorText
10800
11344
  }, {
10801
11345
  command: 'Editor.deleteWordPartLeft',
10802
11346
  key: Alt$1 | Backspace,
@@ -10837,6 +11381,10 @@ const getKeyBindings = () => {
10837
11381
  command: 'Editor.indentLess',
10838
11382
  key: CtrlCmd | BracketLeft,
10839
11383
  when: FocusEditorText
11384
+ }, {
11385
+ command: 'Editor.fold',
11386
+ key: CtrlCmd | Shift | BracketLeft,
11387
+ when: FocusEditorText
10840
11388
  }, {
10841
11389
  command: 'Editor.closeFind',
10842
11390
  key: Escape,
@@ -10861,6 +11409,10 @@ const getKeyBindings = () => {
10861
11409
  command: 'Editor.indentMore',
10862
11410
  key: CtrlCmd | BracketRight,
10863
11411
  when: FocusEditorText
11412
+ }, {
11413
+ command: 'Editor.unfold',
11414
+ key: CtrlCmd | Shift | BracketRight,
11415
+ when: FocusEditorText
10864
11416
  }, {
10865
11417
  command: 'Editor.selectCharacterLeft',
10866
11418
  key: Shift | LeftArrow,
@@ -10889,6 +11441,10 @@ const getKeyBindings = () => {
10889
11441
  command: 'Editor.deleteAllRight',
10890
11442
  key: CtrlCmd | Shift | Delete$1,
10891
11443
  when: FocusEditorText
11444
+ }, {
11445
+ command: 'Editor.deleteLine',
11446
+ key: CtrlCmd | Shift | KeyK,
11447
+ when: FocusEditorText
10892
11448
  }, {
10893
11449
  command: 'Editor.cancelSelection',
10894
11450
  key: Escape,
@@ -10913,6 +11469,10 @@ const getKeyBindings = () => {
10913
11469
  command: 'Editor.cursorDown',
10914
11470
  key: DownArrow,
10915
11471
  when: FocusEditorText
11472
+ }, {
11473
+ command: 'Editor.cursorPageDown',
11474
+ key: PageDown,
11475
+ when: FocusEditorText
10916
11476
  }, {
10917
11477
  command: 'Editor.deleteLeft',
10918
11478
  key: Backspace,
@@ -10945,6 +11505,10 @@ const getKeyBindings = () => {
10945
11505
  command: 'Editor.openRename',
10946
11506
  key: F2,
10947
11507
  when: FocusEditorText
11508
+ }, {
11509
+ command: 'Editor.toggleBreakpoint',
11510
+ key: F9,
11511
+ when: FocusEditorText
10948
11512
  }, {
10949
11513
  command: 'EditorRename.accept',
10950
11514
  key: Enter,
@@ -10965,6 +11529,10 @@ const getKeyBindings = () => {
10965
11529
  command: 'Editor.toggleComment',
10966
11530
  key: CtrlCmd | Slash$1,
10967
11531
  when: FocusEditorText
11532
+ }, {
11533
+ command: 'Editor.toggleBlockComment',
11534
+ key: Alt$1 | Shift | KeyA,
11535
+ when: FocusEditorText
10968
11536
  }, {
10969
11537
  command: 'Editor.copy',
10970
11538
  key: CtrlCmd | KeyC,
@@ -10999,11 +11567,11 @@ const getKeyBindings = () => {
10999
11567
  when: FocusEditorText
11000
11568
  }, {
11001
11569
  command: 'Editor.addCursorAbove',
11002
- key: Alt$1 | Shift | UpArrow,
11570
+ key: Alt$1 | CtrlCmd | UpArrow,
11003
11571
  when: FocusEditorText
11004
11572
  }, {
11005
11573
  command: 'Editor.addCursorBelow',
11006
- key: Alt$1 | Shift | DownArrow,
11574
+ key: Alt$1 | CtrlCmd | DownArrow,
11007
11575
  when: FocusEditorText
11008
11576
  }, {
11009
11577
  command: 'Editor.findAllReferences',
@@ -11120,6 +11688,15 @@ const getProblems = async () => {
11120
11688
 
11121
11689
  const getQuickPickMenuEntries = () => {
11122
11690
  return [{
11691
+ id: 'Editor.fold',
11692
+ label: fold()
11693
+ }, {
11694
+ id: 'Editor.unfold',
11695
+ label: unfold$1()
11696
+ }, {
11697
+ id: 'Editor.deleteLine',
11698
+ label: deleteLine()
11699
+ }, {
11123
11700
  id: 'Editor.format',
11124
11701
  label: formatDocument()
11125
11702
  }, {
@@ -11166,6 +11743,9 @@ const getQuickPickMenuEntries = () => {
11166
11743
  }, {
11167
11744
  id: 'Editor.toggleBlockComment',
11168
11745
  label: toggleBlockComment$1()
11746
+ }, {
11747
+ id: 'Editor.toggleBreakpoint',
11748
+ label: toggleBreakpoint$1()
11169
11749
  }, {
11170
11750
  id: 'Editor.openColorPicker',
11171
11751
  label: editorOpenColorPicker()
@@ -11191,7 +11771,7 @@ const getQuickPickMenuEntries = () => {
11191
11771
  };
11192
11772
 
11193
11773
  const getSelections = editorUid => {
11194
- const editor = getEditor$1(editorUid);
11774
+ const editor = getEditor(editorUid);
11195
11775
  const {
11196
11776
  selections
11197
11777
  } = editor;
@@ -11200,7 +11780,7 @@ const getSelections = editorUid => {
11200
11780
 
11201
11781
  const getText = editorUid => {
11202
11782
  number(editorUid);
11203
- const editor = getEditor$1(editorUid);
11783
+ const editor = getEditor(editorUid);
11204
11784
  const {
11205
11785
  lines
11206
11786
  } = editor;
@@ -11722,6 +12302,13 @@ const registerListener = (listenerType, rpcId) => {
11722
12302
  registerListener$1(listenerType, rpcId);
11723
12303
  };
11724
12304
 
12305
+ const renderAdditionalFocusContext$1 = (oldState, newState) => {
12306
+ if (newState.additionalFocus) {
12307
+ return ['Viewlet.setAdditionalFocus', newState.uid, newState.additionalFocus];
12308
+ }
12309
+ return ['Viewlet.unsetAdditionalFocus', newState.uid, oldState.additionalFocus];
12310
+ };
12311
+
11725
12312
  const getCss = (uid, rowHeight, scrollBarHeight, scrollBarTop, scrollBarWidth, scrollBarLeft) => {
11726
12313
  const editorSelector = `.Editor[data-uid="${uid}"]`;
11727
12314
  return `${editorSelector} {
@@ -12182,7 +12769,6 @@ const getEditorRowsVirtualDom = (textInfos, differences, lineNumbers = true, hig
12182
12769
  className: 'EditorRows',
12183
12770
  onMouseDown: HandleMouseDown,
12184
12771
  onPointerDown: HandlePointerDown,
12185
- onWheel: HandleWheel,
12186
12772
  type: Div
12187
12773
  }, ...rowsDom];
12188
12774
  };
@@ -12270,16 +12856,25 @@ const getEditorContentVirtualDom = ({
12270
12856
  className: 'EditorContent',
12271
12857
  onKeyUp: HandleKeyUp,
12272
12858
  onMouseMove: HandleMouseMove,
12859
+ onWheel: HandleWheel,
12273
12860
  type: Div
12274
12861
  }, ...getEditorInputVirtualDom(), ...getEditorLayersVirtualDom(selectionInfos, textInfos, differences, lineNumbers, highlightedLine, cursorInfos, diagnostics), ...getEditorScrollBarDiagnosticsVirtualDom(scrollBarDiagnostics), ...getScrollBarVirtualDom()];
12275
12862
  };
12276
12863
 
12277
12864
  const getGutterInfoVirtualDom = gutterInfo => {
12865
+ const isBreakpoint = typeof gutterInfo === 'object' && gutterInfo.isBreakpoint;
12866
+ const lineNumber = typeof gutterInfo === 'object' ? gutterInfo.lineNumber : gutterInfo;
12867
+ const label = `Breakpoint on line ${lineNumber}`;
12278
12868
  return [{
12869
+ ...(isBreakpoint && {
12870
+ ariaLabel: label,
12871
+ style: 'color:var(--DebugIconBreakpointForeground,#e51400)',
12872
+ title: label
12873
+ }),
12279
12874
  childCount: 1,
12280
- className: 'LineNumber',
12875
+ className: isBreakpoint ? 'LineNumber LineNumberBreakpoint' : 'LineNumber',
12281
12876
  type: Span
12282
- }, text(gutterInfo)];
12877
+ }, text(isBreakpoint ? '●' : lineNumber)];
12283
12878
  };
12284
12879
  const getEditorGutterVirtualDom$1 = gutterInfos => {
12285
12880
  const dom = gutterInfos.flatMap(getGutterInfoVirtualDom);
@@ -12295,7 +12890,23 @@ const getEditorGutterVirtualDom = gutterInfos => {
12295
12890
  }, ...gutterDom];
12296
12891
  };
12297
12892
 
12893
+ const getGutterInfos = (minLineY, maxLineY, breakPoints, showLineNumbers = true, lineIndices) => {
12894
+ const gutterInfos = [];
12895
+ const rows = lineIndices || Array.from({
12896
+ length: maxLineY - minLineY
12897
+ }, (_, index) => minLineY + index);
12898
+ for (const rowIndex of rows) {
12899
+ const lineNumber = rowIndex + 1;
12900
+ gutterInfos.push(breakPoints.includes(rowIndex) ? {
12901
+ isBreakpoint: true,
12902
+ lineNumber
12903
+ } : showLineNumbers ? lineNumber : '');
12904
+ }
12905
+ return gutterInfos;
12906
+ };
12907
+
12298
12908
  const getEditorVirtualDom = ({
12909
+ breakPoints = [],
12299
12910
  cursorInfos = [],
12300
12911
  diagnostics = [],
12301
12912
  differences,
@@ -12303,10 +12914,13 @@ const getEditorVirtualDom = ({
12303
12914
  highlightedLine = -1,
12304
12915
  lineNumbers = true,
12305
12916
  loadError = '',
12917
+ maxLineY = 0,
12918
+ minLineY = 0,
12306
12919
  scrollBarDiagnostics = [],
12307
12920
  selectionInfos = [],
12308
12921
  textInfos,
12309
- uid
12922
+ uid,
12923
+ visibleLineIndices
12310
12924
  }) => {
12311
12925
  if (loadError) {
12312
12926
  return [{
@@ -12325,9 +12939,11 @@ const getEditorVirtualDom = ({
12325
12939
  type: Div
12326
12940
  }, text(loadError)];
12327
12941
  }
12328
- const gutterDom = lineNumbers ? getEditorGutterVirtualDom(gutterInfos) : [];
12942
+ const visibleGutterInfos = breakPoints.length > 0 || visibleLineIndices ? getGutterInfos(minLineY, maxLineY, breakPoints, lineNumbers, visibleLineIndices) : gutterInfos;
12943
+ const showGutter = lineNumbers || breakPoints.length > 0;
12944
+ const gutterDom = showGutter ? getEditorGutterVirtualDom(visibleGutterInfos) : [];
12329
12945
  return [{
12330
- childCount: lineNumbers ? 2 : 1,
12946
+ childCount: showGutter ? 2 : 1,
12331
12947
  className: 'Viewlet Editor',
12332
12948
  'data-uid': uid,
12333
12949
  onContextMenu: HandleContextMenu,
@@ -12376,6 +12992,8 @@ const renderIncremental = (oldState, newState) => {
12376
12992
 
12377
12993
  const getRenderer = diffType => {
12378
12994
  switch (diffType) {
12995
+ case RenderAdditionalFocusContext:
12996
+ return renderAdditionalFocusContext$1;
12379
12997
  case RenderCss:
12380
12998
  return renderCss$1;
12381
12999
  case RenderFocus:
@@ -12432,13 +13050,13 @@ const renderLines = {
12432
13050
  newState.differences = differences;
12433
13051
  const {
12434
13052
  highlightedLine,
12435
- minLineY
13053
+ visibleLineIndices
12436
13054
  } = newState;
12437
- const relativeLine = highlightedLine - minLineY;
13055
+ const relativeLine = visibleLineIndices.indexOf(highlightedLine);
12438
13056
  const dom = getEditorRowsVirtualDom$1(textInfos, differences, true, relativeLine);
12439
13057
  return [/* method */'setText', dom];
12440
13058
  },
12441
- isEqual: (oldState, newState) => oldState.lines === newState.lines && oldState.tokenizerId === newState.tokenizerId && oldState.minLineY === newState.minLineY && oldState.decorations === newState.decorations && oldState.embeds === newState.embeds && oldState.deltaX === newState.deltaX && oldState.width === newState.width && oldState.highlightedLine === newState.highlightedLine && oldState.debugEnabled === newState.debugEnabled
13059
+ isEqual: (oldState, newState) => oldState.lines === newState.lines && oldState.foldingRanges === newState.foldingRanges && oldState.tokenizerId === newState.tokenizerId && oldState.minLineY === newState.minLineY && oldState.decorations === newState.decorations && oldState.embeds === newState.embeds && oldState.deltaX === newState.deltaX && oldState.width === newState.width && oldState.highlightedLine === newState.highlightedLine && oldState.debugEnabled === newState.debugEnabled
12442
13060
  };
12443
13061
  const renderSelections = {
12444
13062
  apply: (oldState, newState) => {
@@ -12465,13 +13083,8 @@ const renderFocusContext = {
12465
13083
  isEqual: (oldState, newState) => oldState.focus === newState.focus
12466
13084
  };
12467
13085
  const renderAdditionalFocusContext = {
12468
- apply(oldState, newState) {
12469
- if (newState.additionalFocus) {
12470
- return ['Viewlet.setAdditionalFocus', newState.uid, newState.additionalFocus];
12471
- }
12472
- return ['viewlet.unsetAdditionalFocus', newState.uid, newState.additionalFocus];
12473
- },
12474
- isEqual: (oldState, newState) => oldState.additionalFocus === newState.additionalFocus
13086
+ apply: renderAdditionalFocusContext$1,
13087
+ isEqual: isEqual$4
12475
13088
  };
12476
13089
  const renderDecorations = {
12477
13090
  apply(oldState, newState) {
@@ -12483,21 +13096,20 @@ const renderDecorations = {
12483
13096
  const renderGutterInfo = {
12484
13097
  apply(oldState, newState) {
12485
13098
  const {
13099
+ breakPoints,
12486
13100
  lineNumbers,
12487
13101
  maxLineY,
12488
- minLineY
13102
+ minLineY,
13103
+ visibleLineIndices
12489
13104
  } = newState;
12490
- if (!lineNumbers) {
12491
- return [];
12492
- }
12493
- const gutterInfos = [];
12494
- for (let i = minLineY; i < maxLineY; i++) {
12495
- gutterInfos.push(i + 1);
13105
+ if (!lineNumbers && breakPoints.length === 0) {
13106
+ return ['renderGutter', []];
12496
13107
  }
13108
+ const gutterInfos = getGutterInfos(minLineY, maxLineY, breakPoints, lineNumbers, visibleLineIndices);
12497
13109
  const dom = getEditorGutterVirtualDom$1(gutterInfos);
12498
13110
  return ['renderGutter', dom];
12499
13111
  },
12500
- isEqual: (oldState, newState) => oldState.lineNumbers === newState.lineNumbers && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY
13112
+ isEqual: (oldState, newState) => oldState.breakPoints === newState.breakPoints && oldState.foldingRanges === newState.foldingRanges && oldState.lineNumbers === newState.lineNumbers && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY
12501
13113
  };
12502
13114
  const renderWidgets = {
12503
13115
  apply: renderWidgets$1,
@@ -12723,6 +13335,7 @@ const commandMap = {
12723
13335
  'Editor.cancelSelection': wrapCommand(cancelSelection),
12724
13336
  'Editor.closeCodeGenerator': wrapCommand(closeCodeGenerator),
12725
13337
  'Editor.closeColorPicker': wrapCommand(closeColorPicker),
13338
+ 'Editor.closeCompletion': wrapCommand(closeCompletion),
12726
13339
  'Editor.closeFind': wrapCommand(closeFind),
12727
13340
  'Editor.closeFind2': closeFind2,
12728
13341
  'Editor.closeRename': wrapCommand(closeRename),
@@ -12739,10 +13352,13 @@ const commandMap = {
12739
13352
  'Editor.create2': createEditor2,
12740
13353
  'Editor.cursorCharacterLeft': wrapCommand(cursorCharacterLeft),
12741
13354
  'Editor.cursorCharacterRight': wrapCommand(cursorCharacterRight),
13355
+ 'Editor.cursorDocumentEnd': wrapCommand(cursorDocumentEnd),
13356
+ 'Editor.cursorDocumentStart': wrapCommand(cursorDocumentStart),
12742
13357
  'Editor.cursorDown': wrapCommand(cursorDown),
12743
13358
  'Editor.cursorEnd': wrapCommand(cursorEnd),
12744
13359
  'Editor.cursorHome': wrapCommand(cursorHome),
12745
13360
  'Editor.cursorLeft': wrapCommand(cursorCharacterLeft),
13361
+ 'Editor.cursorPageDown': wrapCommand(cursorPageDown),
12746
13362
  'Editor.cursorRight': wrapCommand(cursorCharacterRight),
12747
13363
  'Editor.cursorSet': wrapCommand(cursorSet),
12748
13364
  'Editor.cursorUp': wrapCommand(cursorUp),
@@ -12758,6 +13374,7 @@ const commandMap = {
12758
13374
  'Editor.deleteCharacterRight': wrapCommand(deleteCharacterRight),
12759
13375
  'Editor.deleteHorizontalRight': wrapCommand(editorDeleteHorizontalRight),
12760
13376
  'Editor.deleteLeft': wrapCommand(deleteCharacterLeft),
13377
+ 'Editor.deleteLine': wrapCommand(deleteLine$1),
12761
13378
  'Editor.deleteRight': wrapCommand(deleteCharacterRight),
12762
13379
  'Editor.deleteWordLeft': wrapCommand(deleteWordLeft),
12763
13380
  'Editor.deleteWordPartLeft': wrapCommand(deleteWordPartLeft),
@@ -12767,6 +13384,7 @@ const commandMap = {
12767
13384
  'Editor.dispose': disposeEditor,
12768
13385
  'Editor.executeWidgetCommand': wrapCommand(executeWidgetCommand),
12769
13386
  'Editor.findAllReferences': wrapCommand(findAllReferences$1),
13387
+ 'Editor.fold': wrapCommand(fold$1),
12770
13388
  'Editor.format': wrapCommand(format),
12771
13389
  'Editor.getCommandIds': getCommandIds,
12772
13390
  'Editor.getDiagnostics': getDiagnostics$1,
@@ -12889,20 +13507,22 @@ const commandMap = {
12889
13507
  'Editor.tabCompletion': wrapCommand(tabCompletion),
12890
13508
  'Editor.terminate': terminate,
12891
13509
  'Editor.toggleBlockComment': wrapCommand(toggleBlockComment),
13510
+ 'Editor.toggleBreakpoint': wrapCommand(toggleBreakpoint),
12892
13511
  'Editor.toggleComment': wrapCommand(toggleComment),
12893
13512
  'Editor.toggleLineComment': wrapCommand(editorToggleLineComment),
12894
13513
  'Editor.type': wrapCommand(type),
12895
13514
  'Editor.typeWithAutoClosing': wrapCommand(typeWithAutoClosing),
12896
13515
  'Editor.undo': wrapCommand(undo),
13516
+ 'Editor.unfold': wrapCommand(unfold),
12897
13517
  'Editor.unIndent': wrapCommand(editorUnindent),
12898
13518
  'Editor.updateDebugInfo': updateDebugInfo,
12899
13519
  'Editor.updateDiagnostics': wrapCommand(updateDiagnostics),
12900
- 'EditorCompletion.close': close$4,
13520
+ 'EditorCompletion.close': close$3,
12901
13521
  'EditorCompletion.closeDetails': closeDetails$1,
12902
13522
  'EditorCompletion.focusFirst': focusFirst$1,
12903
13523
  'EditorCompletion.focusIndex': focusIndex$2,
12904
- 'EditorCompletion.focusNext': focusNext$3,
12905
- 'EditorCompletion.focusPrevious': focusPrevious$2,
13524
+ 'EditorCompletion.focusNext': focusNext$2,
13525
+ 'EditorCompletion.focusPrevious': focusPrevious$1,
12906
13526
  'EditorCompletion.handleEditorBlur': handleEditorBlur,
12907
13527
  'EditorCompletion.handleEditorClick': handleEditorClick,
12908
13528
  'EditorCompletion.handleEditorDeleteLeft': handleEditorDeleteLeft$1,
@@ -12929,13 +13549,13 @@ const commandMap = {
12929
13549
  'EditorSourceAction.toggleDetails': toggleDetails,
12930
13550
  'EditorSourceActions.focusNext': focusNext$1,
12931
13551
  'ExtensionHostManagement.activateByEvent': activateByEvent,
12932
- 'FindWidget.close': close$3,
13552
+ 'FindWidget.close': close$4,
12933
13553
  'FindWidget.focusCloseButton': focusCloseButton,
12934
13554
  'FindWidget.focusFind': focusFind,
12935
- 'FindWidget.focusNext': focusNext$2,
13555
+ 'FindWidget.focusNext': focusNext$3,
12936
13556
  'FindWidget.focusNextElement': focusNextElement,
12937
13557
  'FindWidget.focusNextMatchButton': focusNextMatchButton,
12938
- 'FindWidget.focusPrevious': focusPrevious$1,
13558
+ 'FindWidget.focusPrevious': focusPrevious$2,
12939
13559
  'FindWidget.focusPreviousElement': focusPreviousElement,
12940
13560
  'FindWidget.focusPreviousMatchButton': focusPreviousMatchButton,
12941
13561
  'FindWidget.focusReplace': focusReplace,
@@ -13303,7 +13923,7 @@ const EditorCompletionDetailWidget = {
13303
13923
 
13304
13924
  const commandsToForward = [SetDom2, SetCss, AppendToBody, SetBounds2, RegisterEventListeners, SetSelectionByName, SetValueByName, SetFocusContext, SetUid, 'Viewlet.focusSelector'];
13305
13925
  const render$1 = widget => {
13306
- const commands = renderFull$4(widget.oldState, widget.newState);
13926
+ const commands = renderFull$3(widget.oldState, widget.newState);
13307
13927
  const wrappedCommands = [];
13308
13928
  const {
13309
13929
  uid