Leon4gr45 commited on
Commit
1c16487
·
verified ·
1 Parent(s): 0bffd89

Upload folder using huggingface_hub (part 15)

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. node_modules/monaco-editor/esm/vs/editor/common/model.js +133 -0
  3. node_modules/monaco-editor/esm/vs/editor/common/model/decorationProvider.js +1 -0
  4. node_modules/monaco-editor/esm/vs/editor/common/model/editStack.js +359 -0
  5. node_modules/monaco-editor/esm/vs/editor/common/model/fixedArray.js +67 -0
  6. node_modules/monaco-editor/esm/vs/editor/common/model/guidesTextModelPart.js +402 -0
  7. node_modules/monaco-editor/esm/vs/editor/common/model/indentationGuesser.js +176 -0
  8. node_modules/monaco-editor/esm/vs/editor/common/model/intervalTree.js +986 -0
  9. node_modules/monaco-editor/esm/vs/editor/common/model/mirrorTextModel.js +114 -0
  10. node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.js +1452 -0
  11. node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.js +455 -0
  12. node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.js +137 -0
  13. node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.js +360 -0
  14. node_modules/monaco-editor/esm/vs/editor/common/model/prefixSumComputer.js +223 -0
  15. node_modules/monaco-editor/esm/vs/editor/common/model/textModel.js +1899 -0
  16. node_modules/monaco-editor/esm/vs/editor/common/model/textModelPart.js +20 -0
  17. node_modules/monaco-editor/esm/vs/editor/common/model/textModelSearch.js +452 -0
  18. node_modules/monaco-editor/esm/vs/editor/common/model/textModelText.js +20 -0
  19. node_modules/monaco-editor/esm/vs/editor/common/model/textModelTokens.js +429 -0
  20. node_modules/monaco-editor/esm/vs/editor/common/model/tokenizationTextModelPart.js +530 -0
  21. node_modules/monaco-editor/esm/vs/editor/common/model/tokens.js +89 -0
  22. node_modules/monaco-editor/esm/vs/editor/common/model/treeSitterTokens.js +79 -0
  23. node_modules/monaco-editor/esm/vs/editor/common/model/utils.js +31 -0
  24. node_modules/monaco-editor/esm/vs/editor/common/modelLineProjectionData.js +299 -0
  25. node_modules/monaco-editor/esm/vs/editor/common/services/editorBaseApi.js +40 -0
  26. node_modules/monaco-editor/esm/vs/editor/common/services/editorSimpleWorker.js +351 -0
  27. node_modules/monaco-editor/esm/vs/editor/common/services/editorWorker.js +6 -0
  28. node_modules/monaco-editor/esm/vs/editor/common/services/editorWorkerHost.js +13 -0
  29. node_modules/monaco-editor/esm/vs/editor/common/services/findSectionHeaders.js +81 -0
  30. node_modules/monaco-editor/esm/vs/editor/common/services/getIconClasses.js +103 -0
  31. node_modules/monaco-editor/esm/vs/editor/common/services/languageFeatureDebounce.js +135 -0
  32. node_modules/monaco-editor/esm/vs/editor/common/services/languageFeatures.js +6 -0
  33. node_modules/monaco-editor/esm/vs/editor/common/services/languageFeaturesService.js +45 -0
  34. node_modules/monaco-editor/esm/vs/editor/common/services/languageService.js +89 -0
  35. node_modules/monaco-editor/esm/vs/editor/common/services/languagesAssociations.js +190 -0
  36. node_modules/monaco-editor/esm/vs/editor/common/services/languagesRegistry.js +236 -0
  37. node_modules/monaco-editor/esm/vs/editor/common/services/markerDecorations.js +6 -0
  38. node_modules/monaco-editor/esm/vs/editor/common/services/markerDecorationsService.js +227 -0
  39. node_modules/monaco-editor/esm/vs/editor/common/services/model.js +6 -0
  40. node_modules/monaco-editor/esm/vs/editor/common/services/modelService.js +418 -0
  41. node_modules/monaco-editor/esm/vs/editor/common/services/resolverService.js +2 -0
  42. node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensDto.js +79 -0
  43. node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensProviderStyling.js +276 -0
  44. node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensStyling.js +6 -0
  45. node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensStylingService.js +45 -0
  46. node_modules/monaco-editor/esm/vs/editor/common/services/textModelSync/textModelSync.impl.js +304 -0
  47. node_modules/monaco-editor/esm/vs/editor/common/services/textModelSync/textModelSync.protocol.js +5 -0
  48. node_modules/monaco-editor/esm/vs/editor/common/services/textResourceConfiguration.js +3 -0
  49. node_modules/monaco-editor/esm/vs/editor/common/services/treeSitterParserService.js +2 -0
  50. node_modules/monaco-editor/esm/vs/editor/common/services/treeViewsDnd.js +22 -0
.gitattributes CHANGED
@@ -56,3 +56,5 @@ node_modules/lightningcss-linux-x64-gnu/lightningcss.linux-x64-gnu.node filter=l
56
  node_modules/lightningcss-linux-x64-musl/lightningcss.linux-x64-musl.node filter=lfs diff=lfs merge=lfs -text
57
  node_modules/monaco-editor/dev/vs/editor/editor.main.js.map filter=lfs diff=lfs merge=lfs -text
58
  node_modules/monaco-editor/dev/vs/language/typescript/tsWorker.js filter=lfs diff=lfs merge=lfs -text
 
 
 
56
  node_modules/lightningcss-linux-x64-musl/lightningcss.linux-x64-musl.node filter=lfs diff=lfs merge=lfs -text
57
  node_modules/monaco-editor/dev/vs/editor/editor.main.js.map filter=lfs diff=lfs merge=lfs -text
58
  node_modules/monaco-editor/dev/vs/language/typescript/tsWorker.js filter=lfs diff=lfs merge=lfs -text
59
+ node_modules/monaco-editor/esm/vs/language/typescript/ts.worker.js filter=lfs diff=lfs merge=lfs -text
60
+ node_modules/monaco-editor/min-maps/vs/editor/editor.main.js.map filter=lfs diff=lfs merge=lfs -text
node_modules/monaco-editor/esm/vs/editor/common/model.js ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { equals } from '../../base/common/objects.js';
6
+ /**
7
+ * Vertical Lane in the overview ruler of the editor.
8
+ */
9
+ export var OverviewRulerLane;
10
+ (function (OverviewRulerLane) {
11
+ OverviewRulerLane[OverviewRulerLane["Left"] = 1] = "Left";
12
+ OverviewRulerLane[OverviewRulerLane["Center"] = 2] = "Center";
13
+ OverviewRulerLane[OverviewRulerLane["Right"] = 4] = "Right";
14
+ OverviewRulerLane[OverviewRulerLane["Full"] = 7] = "Full";
15
+ })(OverviewRulerLane || (OverviewRulerLane = {}));
16
+ /**
17
+ * Vertical Lane in the glyph margin of the editor.
18
+ */
19
+ export var GlyphMarginLane;
20
+ (function (GlyphMarginLane) {
21
+ GlyphMarginLane[GlyphMarginLane["Left"] = 1] = "Left";
22
+ GlyphMarginLane[GlyphMarginLane["Center"] = 2] = "Center";
23
+ GlyphMarginLane[GlyphMarginLane["Right"] = 3] = "Right";
24
+ })(GlyphMarginLane || (GlyphMarginLane = {}));
25
+ export var InjectedTextCursorStops;
26
+ (function (InjectedTextCursorStops) {
27
+ InjectedTextCursorStops[InjectedTextCursorStops["Both"] = 0] = "Both";
28
+ InjectedTextCursorStops[InjectedTextCursorStops["Right"] = 1] = "Right";
29
+ InjectedTextCursorStops[InjectedTextCursorStops["Left"] = 2] = "Left";
30
+ InjectedTextCursorStops[InjectedTextCursorStops["None"] = 3] = "None";
31
+ })(InjectedTextCursorStops || (InjectedTextCursorStops = {}));
32
+ export class TextModelResolvedOptions {
33
+ get originalIndentSize() {
34
+ return this._indentSizeIsTabSize ? 'tabSize' : this.indentSize;
35
+ }
36
+ /**
37
+ * @internal
38
+ */
39
+ constructor(src) {
40
+ this._textModelResolvedOptionsBrand = undefined;
41
+ this.tabSize = Math.max(1, src.tabSize | 0);
42
+ if (src.indentSize === 'tabSize') {
43
+ this.indentSize = this.tabSize;
44
+ this._indentSizeIsTabSize = true;
45
+ }
46
+ else {
47
+ this.indentSize = Math.max(1, src.indentSize | 0);
48
+ this._indentSizeIsTabSize = false;
49
+ }
50
+ this.insertSpaces = Boolean(src.insertSpaces);
51
+ this.defaultEOL = src.defaultEOL | 0;
52
+ this.trimAutoWhitespace = Boolean(src.trimAutoWhitespace);
53
+ this.bracketPairColorizationOptions = src.bracketPairColorizationOptions;
54
+ }
55
+ /**
56
+ * @internal
57
+ */
58
+ equals(other) {
59
+ return (this.tabSize === other.tabSize
60
+ && this._indentSizeIsTabSize === other._indentSizeIsTabSize
61
+ && this.indentSize === other.indentSize
62
+ && this.insertSpaces === other.insertSpaces
63
+ && this.defaultEOL === other.defaultEOL
64
+ && this.trimAutoWhitespace === other.trimAutoWhitespace
65
+ && equals(this.bracketPairColorizationOptions, other.bracketPairColorizationOptions));
66
+ }
67
+ /**
68
+ * @internal
69
+ */
70
+ createChangeEvent(newOpts) {
71
+ return {
72
+ tabSize: this.tabSize !== newOpts.tabSize,
73
+ indentSize: this.indentSize !== newOpts.indentSize,
74
+ insertSpaces: this.insertSpaces !== newOpts.insertSpaces,
75
+ trimAutoWhitespace: this.trimAutoWhitespace !== newOpts.trimAutoWhitespace,
76
+ };
77
+ }
78
+ }
79
+ export class FindMatch {
80
+ /**
81
+ * @internal
82
+ */
83
+ constructor(range, matches) {
84
+ this._findMatchBrand = undefined;
85
+ this.range = range;
86
+ this.matches = matches;
87
+ }
88
+ }
89
+ /**
90
+ * @internal
91
+ */
92
+ export function isITextSnapshot(obj) {
93
+ return (obj && typeof obj.read === 'function');
94
+ }
95
+ /**
96
+ * @internal
97
+ */
98
+ export class ValidAnnotatedEditOperation {
99
+ constructor(identifier, range, text, forceMoveMarkers, isAutoWhitespaceEdit, _isTracked) {
100
+ this.identifier = identifier;
101
+ this.range = range;
102
+ this.text = text;
103
+ this.forceMoveMarkers = forceMoveMarkers;
104
+ this.isAutoWhitespaceEdit = isAutoWhitespaceEdit;
105
+ this._isTracked = _isTracked;
106
+ }
107
+ }
108
+ /**
109
+ * @internal
110
+ */
111
+ export class SearchData {
112
+ constructor(regex, wordSeparators, simpleSearch) {
113
+ this.regex = regex;
114
+ this.wordSeparators = wordSeparators;
115
+ this.simpleSearch = simpleSearch;
116
+ }
117
+ }
118
+ /**
119
+ * @internal
120
+ */
121
+ export class ApplyEditsResult {
122
+ constructor(reverseEdits, changes, trimAutoWhitespaceLineNumbers) {
123
+ this.reverseEdits = reverseEdits;
124
+ this.changes = changes;
125
+ this.trimAutoWhitespaceLineNumbers = trimAutoWhitespaceLineNumbers;
126
+ }
127
+ }
128
+ /**
129
+ * @internal
130
+ */
131
+ export function shouldSynchronizeModel(model) {
132
+ return (!model.isTooLargeForSyncing() && !model.isForSimpleWidget);
133
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/decorationProvider.js ADDED
@@ -0,0 +1 @@
 
 
1
+ export {};
node_modules/monaco-editor/esm/vs/editor/common/model/editStack.js ADDED
@@ -0,0 +1,359 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import * as nls from '../../../nls.js';
6
+ import { onUnexpectedError } from '../../../base/common/errors.js';
7
+ import { Selection } from '../core/selection.js';
8
+ import { URI } from '../../../base/common/uri.js';
9
+ import { TextChange, compressConsecutiveTextChanges } from '../core/textChange.js';
10
+ import * as buffer from '../../../base/common/buffer.js';
11
+ import { basename } from '../../../base/common/resources.js';
12
+ function uriGetComparisonKey(resource) {
13
+ return resource.toString();
14
+ }
15
+ export class SingleModelEditStackData {
16
+ static create(model, beforeCursorState) {
17
+ const alternativeVersionId = model.getAlternativeVersionId();
18
+ const eol = getModelEOL(model);
19
+ return new SingleModelEditStackData(alternativeVersionId, alternativeVersionId, eol, eol, beforeCursorState, beforeCursorState, []);
20
+ }
21
+ constructor(beforeVersionId, afterVersionId, beforeEOL, afterEOL, beforeCursorState, afterCursorState, changes) {
22
+ this.beforeVersionId = beforeVersionId;
23
+ this.afterVersionId = afterVersionId;
24
+ this.beforeEOL = beforeEOL;
25
+ this.afterEOL = afterEOL;
26
+ this.beforeCursorState = beforeCursorState;
27
+ this.afterCursorState = afterCursorState;
28
+ this.changes = changes;
29
+ }
30
+ append(model, textChanges, afterEOL, afterVersionId, afterCursorState) {
31
+ if (textChanges.length > 0) {
32
+ this.changes = compressConsecutiveTextChanges(this.changes, textChanges);
33
+ }
34
+ this.afterEOL = afterEOL;
35
+ this.afterVersionId = afterVersionId;
36
+ this.afterCursorState = afterCursorState;
37
+ }
38
+ static _writeSelectionsSize(selections) {
39
+ return 4 + 4 * 4 * (selections ? selections.length : 0);
40
+ }
41
+ static _writeSelections(b, selections, offset) {
42
+ buffer.writeUInt32BE(b, (selections ? selections.length : 0), offset);
43
+ offset += 4;
44
+ if (selections) {
45
+ for (const selection of selections) {
46
+ buffer.writeUInt32BE(b, selection.selectionStartLineNumber, offset);
47
+ offset += 4;
48
+ buffer.writeUInt32BE(b, selection.selectionStartColumn, offset);
49
+ offset += 4;
50
+ buffer.writeUInt32BE(b, selection.positionLineNumber, offset);
51
+ offset += 4;
52
+ buffer.writeUInt32BE(b, selection.positionColumn, offset);
53
+ offset += 4;
54
+ }
55
+ }
56
+ return offset;
57
+ }
58
+ static _readSelections(b, offset, dest) {
59
+ const count = buffer.readUInt32BE(b, offset);
60
+ offset += 4;
61
+ for (let i = 0; i < count; i++) {
62
+ const selectionStartLineNumber = buffer.readUInt32BE(b, offset);
63
+ offset += 4;
64
+ const selectionStartColumn = buffer.readUInt32BE(b, offset);
65
+ offset += 4;
66
+ const positionLineNumber = buffer.readUInt32BE(b, offset);
67
+ offset += 4;
68
+ const positionColumn = buffer.readUInt32BE(b, offset);
69
+ offset += 4;
70
+ dest.push(new Selection(selectionStartLineNumber, selectionStartColumn, positionLineNumber, positionColumn));
71
+ }
72
+ return offset;
73
+ }
74
+ serialize() {
75
+ let necessarySize = (+4 // beforeVersionId
76
+ + 4 // afterVersionId
77
+ + 1 // beforeEOL
78
+ + 1 // afterEOL
79
+ + SingleModelEditStackData._writeSelectionsSize(this.beforeCursorState)
80
+ + SingleModelEditStackData._writeSelectionsSize(this.afterCursorState)
81
+ + 4 // change count
82
+ );
83
+ for (const change of this.changes) {
84
+ necessarySize += change.writeSize();
85
+ }
86
+ const b = new Uint8Array(necessarySize);
87
+ let offset = 0;
88
+ buffer.writeUInt32BE(b, this.beforeVersionId, offset);
89
+ offset += 4;
90
+ buffer.writeUInt32BE(b, this.afterVersionId, offset);
91
+ offset += 4;
92
+ buffer.writeUInt8(b, this.beforeEOL, offset);
93
+ offset += 1;
94
+ buffer.writeUInt8(b, this.afterEOL, offset);
95
+ offset += 1;
96
+ offset = SingleModelEditStackData._writeSelections(b, this.beforeCursorState, offset);
97
+ offset = SingleModelEditStackData._writeSelections(b, this.afterCursorState, offset);
98
+ buffer.writeUInt32BE(b, this.changes.length, offset);
99
+ offset += 4;
100
+ for (const change of this.changes) {
101
+ offset = change.write(b, offset);
102
+ }
103
+ return b.buffer;
104
+ }
105
+ static deserialize(source) {
106
+ const b = new Uint8Array(source);
107
+ let offset = 0;
108
+ const beforeVersionId = buffer.readUInt32BE(b, offset);
109
+ offset += 4;
110
+ const afterVersionId = buffer.readUInt32BE(b, offset);
111
+ offset += 4;
112
+ const beforeEOL = buffer.readUInt8(b, offset);
113
+ offset += 1;
114
+ const afterEOL = buffer.readUInt8(b, offset);
115
+ offset += 1;
116
+ const beforeCursorState = [];
117
+ offset = SingleModelEditStackData._readSelections(b, offset, beforeCursorState);
118
+ const afterCursorState = [];
119
+ offset = SingleModelEditStackData._readSelections(b, offset, afterCursorState);
120
+ const changeCount = buffer.readUInt32BE(b, offset);
121
+ offset += 4;
122
+ const changes = [];
123
+ for (let i = 0; i < changeCount; i++) {
124
+ offset = TextChange.read(b, offset, changes);
125
+ }
126
+ return new SingleModelEditStackData(beforeVersionId, afterVersionId, beforeEOL, afterEOL, beforeCursorState, afterCursorState, changes);
127
+ }
128
+ }
129
+ export class SingleModelEditStackElement {
130
+ get type() {
131
+ return 0 /* UndoRedoElementType.Resource */;
132
+ }
133
+ get resource() {
134
+ if (URI.isUri(this.model)) {
135
+ return this.model;
136
+ }
137
+ return this.model.uri;
138
+ }
139
+ constructor(label, code, model, beforeCursorState) {
140
+ this.label = label;
141
+ this.code = code;
142
+ this.model = model;
143
+ this._data = SingleModelEditStackData.create(model, beforeCursorState);
144
+ }
145
+ toString() {
146
+ const data = (this._data instanceof SingleModelEditStackData ? this._data : SingleModelEditStackData.deserialize(this._data));
147
+ return data.changes.map(change => change.toString()).join(', ');
148
+ }
149
+ matchesResource(resource) {
150
+ const uri = (URI.isUri(this.model) ? this.model : this.model.uri);
151
+ return (uri.toString() === resource.toString());
152
+ }
153
+ setModel(model) {
154
+ this.model = model;
155
+ }
156
+ canAppend(model) {
157
+ return (this.model === model && this._data instanceof SingleModelEditStackData);
158
+ }
159
+ append(model, textChanges, afterEOL, afterVersionId, afterCursorState) {
160
+ if (this._data instanceof SingleModelEditStackData) {
161
+ this._data.append(model, textChanges, afterEOL, afterVersionId, afterCursorState);
162
+ }
163
+ }
164
+ close() {
165
+ if (this._data instanceof SingleModelEditStackData) {
166
+ this._data = this._data.serialize();
167
+ }
168
+ }
169
+ open() {
170
+ if (!(this._data instanceof SingleModelEditStackData)) {
171
+ this._data = SingleModelEditStackData.deserialize(this._data);
172
+ }
173
+ }
174
+ undo() {
175
+ if (URI.isUri(this.model)) {
176
+ // don't have a model
177
+ throw new Error(`Invalid SingleModelEditStackElement`);
178
+ }
179
+ if (this._data instanceof SingleModelEditStackData) {
180
+ this._data = this._data.serialize();
181
+ }
182
+ const data = SingleModelEditStackData.deserialize(this._data);
183
+ this.model._applyUndo(data.changes, data.beforeEOL, data.beforeVersionId, data.beforeCursorState);
184
+ }
185
+ redo() {
186
+ if (URI.isUri(this.model)) {
187
+ // don't have a model
188
+ throw new Error(`Invalid SingleModelEditStackElement`);
189
+ }
190
+ if (this._data instanceof SingleModelEditStackData) {
191
+ this._data = this._data.serialize();
192
+ }
193
+ const data = SingleModelEditStackData.deserialize(this._data);
194
+ this.model._applyRedo(data.changes, data.afterEOL, data.afterVersionId, data.afterCursorState);
195
+ }
196
+ heapSize() {
197
+ if (this._data instanceof SingleModelEditStackData) {
198
+ this._data = this._data.serialize();
199
+ }
200
+ return this._data.byteLength + 168 /*heap overhead*/;
201
+ }
202
+ }
203
+ export class MultiModelEditStackElement {
204
+ get resources() {
205
+ return this._editStackElementsArr.map(editStackElement => editStackElement.resource);
206
+ }
207
+ constructor(label, code, editStackElements) {
208
+ this.label = label;
209
+ this.code = code;
210
+ this.type = 1 /* UndoRedoElementType.Workspace */;
211
+ this._isOpen = true;
212
+ this._editStackElementsArr = editStackElements.slice(0);
213
+ this._editStackElementsMap = new Map();
214
+ for (const editStackElement of this._editStackElementsArr) {
215
+ const key = uriGetComparisonKey(editStackElement.resource);
216
+ this._editStackElementsMap.set(key, editStackElement);
217
+ }
218
+ this._delegate = null;
219
+ }
220
+ prepareUndoRedo() {
221
+ if (this._delegate) {
222
+ return this._delegate.prepareUndoRedo(this);
223
+ }
224
+ }
225
+ matchesResource(resource) {
226
+ const key = uriGetComparisonKey(resource);
227
+ return (this._editStackElementsMap.has(key));
228
+ }
229
+ setModel(model) {
230
+ const key = uriGetComparisonKey(URI.isUri(model) ? model : model.uri);
231
+ if (this._editStackElementsMap.has(key)) {
232
+ this._editStackElementsMap.get(key).setModel(model);
233
+ }
234
+ }
235
+ canAppend(model) {
236
+ if (!this._isOpen) {
237
+ return false;
238
+ }
239
+ const key = uriGetComparisonKey(model.uri);
240
+ if (this._editStackElementsMap.has(key)) {
241
+ const editStackElement = this._editStackElementsMap.get(key);
242
+ return editStackElement.canAppend(model);
243
+ }
244
+ return false;
245
+ }
246
+ append(model, textChanges, afterEOL, afterVersionId, afterCursorState) {
247
+ const key = uriGetComparisonKey(model.uri);
248
+ const editStackElement = this._editStackElementsMap.get(key);
249
+ editStackElement.append(model, textChanges, afterEOL, afterVersionId, afterCursorState);
250
+ }
251
+ close() {
252
+ this._isOpen = false;
253
+ }
254
+ open() {
255
+ // cannot reopen
256
+ }
257
+ undo() {
258
+ this._isOpen = false;
259
+ for (const editStackElement of this._editStackElementsArr) {
260
+ editStackElement.undo();
261
+ }
262
+ }
263
+ redo() {
264
+ for (const editStackElement of this._editStackElementsArr) {
265
+ editStackElement.redo();
266
+ }
267
+ }
268
+ heapSize(resource) {
269
+ const key = uriGetComparisonKey(resource);
270
+ if (this._editStackElementsMap.has(key)) {
271
+ const editStackElement = this._editStackElementsMap.get(key);
272
+ return editStackElement.heapSize();
273
+ }
274
+ return 0;
275
+ }
276
+ split() {
277
+ return this._editStackElementsArr;
278
+ }
279
+ toString() {
280
+ const result = [];
281
+ for (const editStackElement of this._editStackElementsArr) {
282
+ result.push(`${basename(editStackElement.resource)}: ${editStackElement}`);
283
+ }
284
+ return `{${result.join(', ')}}`;
285
+ }
286
+ }
287
+ function getModelEOL(model) {
288
+ const eol = model.getEOL();
289
+ if (eol === '\n') {
290
+ return 0 /* EndOfLineSequence.LF */;
291
+ }
292
+ else {
293
+ return 1 /* EndOfLineSequence.CRLF */;
294
+ }
295
+ }
296
+ export function isEditStackElement(element) {
297
+ if (!element) {
298
+ return false;
299
+ }
300
+ return ((element instanceof SingleModelEditStackElement) || (element instanceof MultiModelEditStackElement));
301
+ }
302
+ export class EditStack {
303
+ constructor(model, undoRedoService) {
304
+ this._model = model;
305
+ this._undoRedoService = undoRedoService;
306
+ }
307
+ pushStackElement() {
308
+ const lastElement = this._undoRedoService.getLastElement(this._model.uri);
309
+ if (isEditStackElement(lastElement)) {
310
+ lastElement.close();
311
+ }
312
+ }
313
+ popStackElement() {
314
+ const lastElement = this._undoRedoService.getLastElement(this._model.uri);
315
+ if (isEditStackElement(lastElement)) {
316
+ lastElement.open();
317
+ }
318
+ }
319
+ clear() {
320
+ this._undoRedoService.removeElements(this._model.uri);
321
+ }
322
+ _getOrCreateEditStackElement(beforeCursorState, group) {
323
+ const lastElement = this._undoRedoService.getLastElement(this._model.uri);
324
+ if (isEditStackElement(lastElement) && lastElement.canAppend(this._model)) {
325
+ return lastElement;
326
+ }
327
+ const newElement = new SingleModelEditStackElement(nls.localize('edit', "Typing"), 'undoredo.textBufferEdit', this._model, beforeCursorState);
328
+ this._undoRedoService.pushElement(newElement, group);
329
+ return newElement;
330
+ }
331
+ pushEOL(eol) {
332
+ const editStackElement = this._getOrCreateEditStackElement(null, undefined);
333
+ this._model.setEOL(eol);
334
+ editStackElement.append(this._model, [], getModelEOL(this._model), this._model.getAlternativeVersionId(), null);
335
+ }
336
+ pushEditOperation(beforeCursorState, editOperations, cursorStateComputer, group) {
337
+ const editStackElement = this._getOrCreateEditStackElement(beforeCursorState, group);
338
+ const inverseEditOperations = this._model.applyEdits(editOperations, true);
339
+ const afterCursorState = EditStack._computeCursorState(cursorStateComputer, inverseEditOperations);
340
+ const textChanges = inverseEditOperations.map((op, index) => ({ index: index, textChange: op.textChange }));
341
+ textChanges.sort((a, b) => {
342
+ if (a.textChange.oldPosition === b.textChange.oldPosition) {
343
+ return a.index - b.index;
344
+ }
345
+ return a.textChange.oldPosition - b.textChange.oldPosition;
346
+ });
347
+ editStackElement.append(this._model, textChanges.map(op => op.textChange), getModelEOL(this._model), this._model.getAlternativeVersionId(), afterCursorState);
348
+ return afterCursorState;
349
+ }
350
+ static _computeCursorState(cursorStateComputer, inverseEditOperations) {
351
+ try {
352
+ return cursorStateComputer ? cursorStateComputer(inverseEditOperations) : null;
353
+ }
354
+ catch (e) {
355
+ onUnexpectedError(e);
356
+ return null;
357
+ }
358
+ }
359
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/fixedArray.js ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { arrayInsert } from '../../../base/common/arrays.js';
6
+ /**
7
+ * An array that avoids being sparse by always
8
+ * filling up unused indices with a default value.
9
+ */
10
+ export class FixedArray {
11
+ constructor(_default) {
12
+ this._default = _default;
13
+ this._store = [];
14
+ }
15
+ get(index) {
16
+ if (index < this._store.length) {
17
+ return this._store[index];
18
+ }
19
+ return this._default;
20
+ }
21
+ set(index, value) {
22
+ while (index >= this._store.length) {
23
+ this._store[this._store.length] = this._default;
24
+ }
25
+ this._store[index] = value;
26
+ }
27
+ replace(index, oldLength, newLength) {
28
+ if (index >= this._store.length) {
29
+ return;
30
+ }
31
+ if (oldLength === 0) {
32
+ this.insert(index, newLength);
33
+ return;
34
+ }
35
+ else if (newLength === 0) {
36
+ this.delete(index, oldLength);
37
+ return;
38
+ }
39
+ const before = this._store.slice(0, index);
40
+ const after = this._store.slice(index + oldLength);
41
+ const insertArr = arrayFill(newLength, this._default);
42
+ this._store = before.concat(insertArr, after);
43
+ }
44
+ delete(deleteIndex, deleteCount) {
45
+ if (deleteCount === 0 || deleteIndex >= this._store.length) {
46
+ return;
47
+ }
48
+ this._store.splice(deleteIndex, deleteCount);
49
+ }
50
+ insert(insertIndex, insertCount) {
51
+ if (insertCount === 0 || insertIndex >= this._store.length) {
52
+ return;
53
+ }
54
+ const arr = [];
55
+ for (let i = 0; i < insertCount; i++) {
56
+ arr[i] = this._default;
57
+ }
58
+ this._store = arrayInsert(this._store, insertIndex, arr);
59
+ }
60
+ }
61
+ function arrayFill(length, value) {
62
+ const arr = [];
63
+ for (let i = 0; i < length; i++) {
64
+ arr[i] = value;
65
+ }
66
+ return arr;
67
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/guidesTextModelPart.js ADDED
@@ -0,0 +1,402 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { findLast } from '../../../base/common/arraysFind.js';
6
+ import * as strings from '../../../base/common/strings.js';
7
+ import { CursorColumns } from '../core/cursorColumns.js';
8
+ import { Range } from '../core/range.js';
9
+ import { TextModelPart } from './textModelPart.js';
10
+ import { computeIndentLevel } from './utils.js';
11
+ import { HorizontalGuidesState, IndentGuide, IndentGuideHorizontalLine } from '../textModelGuides.js';
12
+ import { BugIndicatingError } from '../../../base/common/errors.js';
13
+ export class GuidesTextModelPart extends TextModelPart {
14
+ constructor(textModel, languageConfigurationService) {
15
+ super();
16
+ this.textModel = textModel;
17
+ this.languageConfigurationService = languageConfigurationService;
18
+ }
19
+ getLanguageConfiguration(languageId) {
20
+ return this.languageConfigurationService.getLanguageConfiguration(languageId);
21
+ }
22
+ _computeIndentLevel(lineIndex) {
23
+ return computeIndentLevel(this.textModel.getLineContent(lineIndex + 1), this.textModel.getOptions().tabSize);
24
+ }
25
+ getActiveIndentGuide(lineNumber, minLineNumber, maxLineNumber) {
26
+ this.assertNotDisposed();
27
+ const lineCount = this.textModel.getLineCount();
28
+ if (lineNumber < 1 || lineNumber > lineCount) {
29
+ throw new BugIndicatingError('Illegal value for lineNumber');
30
+ }
31
+ const foldingRules = this.getLanguageConfiguration(this.textModel.getLanguageId()).foldingRules;
32
+ const offSide = Boolean(foldingRules && foldingRules.offSide);
33
+ let up_aboveContentLineIndex = -2; /* -2 is a marker for not having computed it */
34
+ let up_aboveContentLineIndent = -1;
35
+ let up_belowContentLineIndex = -2; /* -2 is a marker for not having computed it */
36
+ let up_belowContentLineIndent = -1;
37
+ const up_resolveIndents = (lineNumber) => {
38
+ if (up_aboveContentLineIndex !== -1 &&
39
+ (up_aboveContentLineIndex === -2 ||
40
+ up_aboveContentLineIndex > lineNumber - 1)) {
41
+ up_aboveContentLineIndex = -1;
42
+ up_aboveContentLineIndent = -1;
43
+ // must find previous line with content
44
+ for (let lineIndex = lineNumber - 2; lineIndex >= 0; lineIndex--) {
45
+ const indent = this._computeIndentLevel(lineIndex);
46
+ if (indent >= 0) {
47
+ up_aboveContentLineIndex = lineIndex;
48
+ up_aboveContentLineIndent = indent;
49
+ break;
50
+ }
51
+ }
52
+ }
53
+ if (up_belowContentLineIndex === -2) {
54
+ up_belowContentLineIndex = -1;
55
+ up_belowContentLineIndent = -1;
56
+ // must find next line with content
57
+ for (let lineIndex = lineNumber; lineIndex < lineCount; lineIndex++) {
58
+ const indent = this._computeIndentLevel(lineIndex);
59
+ if (indent >= 0) {
60
+ up_belowContentLineIndex = lineIndex;
61
+ up_belowContentLineIndent = indent;
62
+ break;
63
+ }
64
+ }
65
+ }
66
+ };
67
+ let down_aboveContentLineIndex = -2; /* -2 is a marker for not having computed it */
68
+ let down_aboveContentLineIndent = -1;
69
+ let down_belowContentLineIndex = -2; /* -2 is a marker for not having computed it */
70
+ let down_belowContentLineIndent = -1;
71
+ const down_resolveIndents = (lineNumber) => {
72
+ if (down_aboveContentLineIndex === -2) {
73
+ down_aboveContentLineIndex = -1;
74
+ down_aboveContentLineIndent = -1;
75
+ // must find previous line with content
76
+ for (let lineIndex = lineNumber - 2; lineIndex >= 0; lineIndex--) {
77
+ const indent = this._computeIndentLevel(lineIndex);
78
+ if (indent >= 0) {
79
+ down_aboveContentLineIndex = lineIndex;
80
+ down_aboveContentLineIndent = indent;
81
+ break;
82
+ }
83
+ }
84
+ }
85
+ if (down_belowContentLineIndex !== -1 &&
86
+ (down_belowContentLineIndex === -2 ||
87
+ down_belowContentLineIndex < lineNumber - 1)) {
88
+ down_belowContentLineIndex = -1;
89
+ down_belowContentLineIndent = -1;
90
+ // must find next line with content
91
+ for (let lineIndex = lineNumber; lineIndex < lineCount; lineIndex++) {
92
+ const indent = this._computeIndentLevel(lineIndex);
93
+ if (indent >= 0) {
94
+ down_belowContentLineIndex = lineIndex;
95
+ down_belowContentLineIndent = indent;
96
+ break;
97
+ }
98
+ }
99
+ }
100
+ };
101
+ let startLineNumber = 0;
102
+ let goUp = true;
103
+ let endLineNumber = 0;
104
+ let goDown = true;
105
+ let indent = 0;
106
+ let initialIndent = 0;
107
+ for (let distance = 0; goUp || goDown; distance++) {
108
+ const upLineNumber = lineNumber - distance;
109
+ const downLineNumber = lineNumber + distance;
110
+ if (distance > 1 && (upLineNumber < 1 || upLineNumber < minLineNumber)) {
111
+ goUp = false;
112
+ }
113
+ if (distance > 1 &&
114
+ (downLineNumber > lineCount || downLineNumber > maxLineNumber)) {
115
+ goDown = false;
116
+ }
117
+ if (distance > 50000) {
118
+ // stop processing
119
+ goUp = false;
120
+ goDown = false;
121
+ }
122
+ let upLineIndentLevel = -1;
123
+ if (goUp && upLineNumber >= 1) {
124
+ // compute indent level going up
125
+ const currentIndent = this._computeIndentLevel(upLineNumber - 1);
126
+ if (currentIndent >= 0) {
127
+ // This line has content (besides whitespace)
128
+ // Use the line's indent
129
+ up_belowContentLineIndex = upLineNumber - 1;
130
+ up_belowContentLineIndent = currentIndent;
131
+ upLineIndentLevel = Math.ceil(currentIndent / this.textModel.getOptions().indentSize);
132
+ }
133
+ else {
134
+ up_resolveIndents(upLineNumber);
135
+ upLineIndentLevel = this._getIndentLevelForWhitespaceLine(offSide, up_aboveContentLineIndent, up_belowContentLineIndent);
136
+ }
137
+ }
138
+ let downLineIndentLevel = -1;
139
+ if (goDown && downLineNumber <= lineCount) {
140
+ // compute indent level going down
141
+ const currentIndent = this._computeIndentLevel(downLineNumber - 1);
142
+ if (currentIndent >= 0) {
143
+ // This line has content (besides whitespace)
144
+ // Use the line's indent
145
+ down_aboveContentLineIndex = downLineNumber - 1;
146
+ down_aboveContentLineIndent = currentIndent;
147
+ downLineIndentLevel = Math.ceil(currentIndent / this.textModel.getOptions().indentSize);
148
+ }
149
+ else {
150
+ down_resolveIndents(downLineNumber);
151
+ downLineIndentLevel = this._getIndentLevelForWhitespaceLine(offSide, down_aboveContentLineIndent, down_belowContentLineIndent);
152
+ }
153
+ }
154
+ if (distance === 0) {
155
+ initialIndent = upLineIndentLevel;
156
+ continue;
157
+ }
158
+ if (distance === 1) {
159
+ if (downLineNumber <= lineCount &&
160
+ downLineIndentLevel >= 0 &&
161
+ initialIndent + 1 === downLineIndentLevel) {
162
+ // This is the beginning of a scope, we have special handling here, since we want the
163
+ // child scope indent to be active, not the parent scope
164
+ goUp = false;
165
+ startLineNumber = downLineNumber;
166
+ endLineNumber = downLineNumber;
167
+ indent = downLineIndentLevel;
168
+ continue;
169
+ }
170
+ if (upLineNumber >= 1 &&
171
+ upLineIndentLevel >= 0 &&
172
+ upLineIndentLevel - 1 === initialIndent) {
173
+ // This is the end of a scope, just like above
174
+ goDown = false;
175
+ startLineNumber = upLineNumber;
176
+ endLineNumber = upLineNumber;
177
+ indent = upLineIndentLevel;
178
+ continue;
179
+ }
180
+ startLineNumber = lineNumber;
181
+ endLineNumber = lineNumber;
182
+ indent = initialIndent;
183
+ if (indent === 0) {
184
+ // No need to continue
185
+ return { startLineNumber, endLineNumber, indent };
186
+ }
187
+ }
188
+ if (goUp) {
189
+ if (upLineIndentLevel >= indent) {
190
+ startLineNumber = upLineNumber;
191
+ }
192
+ else {
193
+ goUp = false;
194
+ }
195
+ }
196
+ if (goDown) {
197
+ if (downLineIndentLevel >= indent) {
198
+ endLineNumber = downLineNumber;
199
+ }
200
+ else {
201
+ goDown = false;
202
+ }
203
+ }
204
+ }
205
+ return { startLineNumber, endLineNumber, indent };
206
+ }
207
+ getLinesBracketGuides(startLineNumber, endLineNumber, activePosition, options) {
208
+ const result = [];
209
+ for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
210
+ result.push([]);
211
+ }
212
+ // If requested, this could be made configurable.
213
+ const includeSingleLinePairs = true;
214
+ const bracketPairs = this.textModel.bracketPairs.getBracketPairsInRangeWithMinIndentation(new Range(startLineNumber, 1, endLineNumber, this.textModel.getLineMaxColumn(endLineNumber))).toArray();
215
+ let activeBracketPairRange = undefined;
216
+ if (activePosition && bracketPairs.length > 0) {
217
+ const bracketsContainingActivePosition = (startLineNumber <= activePosition.lineNumber &&
218
+ activePosition.lineNumber <= endLineNumber
219
+ // We don't need to query the brackets again if the cursor is in the viewport
220
+ ? bracketPairs
221
+ : this.textModel.bracketPairs.getBracketPairsInRange(Range.fromPositions(activePosition)).toArray()).filter((bp) => Range.strictContainsPosition(bp.range, activePosition));
222
+ activeBracketPairRange = findLast(bracketsContainingActivePosition, (i) => includeSingleLinePairs || i.range.startLineNumber !== i.range.endLineNumber)?.range;
223
+ }
224
+ const independentColorPoolPerBracketType = this.textModel.getOptions().bracketPairColorizationOptions.independentColorPoolPerBracketType;
225
+ const colorProvider = new BracketPairGuidesClassNames();
226
+ for (const pair of bracketPairs) {
227
+ /*
228
+
229
+
230
+ {
231
+ |
232
+ }
233
+
234
+ {
235
+ |
236
+ ----}
237
+
238
+ ____{
239
+ |test
240
+ ----}
241
+
242
+ renderHorizontalEndLineAtTheBottom:
243
+ {
244
+ |
245
+ |x}
246
+ --
247
+ renderHorizontalEndLineAtTheBottom:
248
+ ____{
249
+ |test
250
+ | x }
251
+ ----
252
+ */
253
+ if (!pair.closingBracketRange) {
254
+ continue;
255
+ }
256
+ const isActive = activeBracketPairRange && pair.range.equalsRange(activeBracketPairRange);
257
+ if (!isActive && !options.includeInactive) {
258
+ continue;
259
+ }
260
+ const className = colorProvider.getInlineClassName(pair.nestingLevel, pair.nestingLevelOfEqualBracketType, independentColorPoolPerBracketType) +
261
+ (options.highlightActive && isActive
262
+ ? ' ' + colorProvider.activeClassName
263
+ : '');
264
+ const start = pair.openingBracketRange.getStartPosition();
265
+ const end = pair.closingBracketRange.getStartPosition();
266
+ const horizontalGuides = options.horizontalGuides === HorizontalGuidesState.Enabled || (options.horizontalGuides === HorizontalGuidesState.EnabledForActive && isActive);
267
+ if (pair.range.startLineNumber === pair.range.endLineNumber) {
268
+ if (includeSingleLinePairs && horizontalGuides) {
269
+ result[pair.range.startLineNumber - startLineNumber].push(new IndentGuide(-1, pair.openingBracketRange.getEndPosition().column, className, new IndentGuideHorizontalLine(false, end.column), -1, -1));
270
+ }
271
+ continue;
272
+ }
273
+ const endVisibleColumn = this.getVisibleColumnFromPosition(end);
274
+ const startVisibleColumn = this.getVisibleColumnFromPosition(pair.openingBracketRange.getStartPosition());
275
+ const guideVisibleColumn = Math.min(startVisibleColumn, endVisibleColumn, pair.minVisibleColumnIndentation + 1);
276
+ let renderHorizontalEndLineAtTheBottom = false;
277
+ const firstNonWsIndex = strings.firstNonWhitespaceIndex(this.textModel.getLineContent(pair.closingBracketRange.startLineNumber));
278
+ const hasTextBeforeClosingBracket = firstNonWsIndex < pair.closingBracketRange.startColumn - 1;
279
+ if (hasTextBeforeClosingBracket) {
280
+ renderHorizontalEndLineAtTheBottom = true;
281
+ }
282
+ const visibleGuideStartLineNumber = Math.max(start.lineNumber, startLineNumber);
283
+ const visibleGuideEndLineNumber = Math.min(end.lineNumber, endLineNumber);
284
+ const offset = renderHorizontalEndLineAtTheBottom ? 1 : 0;
285
+ for (let l = visibleGuideStartLineNumber; l < visibleGuideEndLineNumber + offset; l++) {
286
+ result[l - startLineNumber].push(new IndentGuide(guideVisibleColumn, -1, className, null, l === start.lineNumber ? start.column : -1, l === end.lineNumber ? end.column : -1));
287
+ }
288
+ if (horizontalGuides) {
289
+ if (start.lineNumber >= startLineNumber && startVisibleColumn > guideVisibleColumn) {
290
+ result[start.lineNumber - startLineNumber].push(new IndentGuide(guideVisibleColumn, -1, className, new IndentGuideHorizontalLine(false, start.column), -1, -1));
291
+ }
292
+ if (end.lineNumber <= endLineNumber && endVisibleColumn > guideVisibleColumn) {
293
+ result[end.lineNumber - startLineNumber].push(new IndentGuide(guideVisibleColumn, -1, className, new IndentGuideHorizontalLine(!renderHorizontalEndLineAtTheBottom, end.column), -1, -1));
294
+ }
295
+ }
296
+ }
297
+ for (const guides of result) {
298
+ guides.sort((a, b) => a.visibleColumn - b.visibleColumn);
299
+ }
300
+ return result;
301
+ }
302
+ getVisibleColumnFromPosition(position) {
303
+ return (CursorColumns.visibleColumnFromColumn(this.textModel.getLineContent(position.lineNumber), position.column, this.textModel.getOptions().tabSize) + 1);
304
+ }
305
+ getLinesIndentGuides(startLineNumber, endLineNumber) {
306
+ this.assertNotDisposed();
307
+ const lineCount = this.textModel.getLineCount();
308
+ if (startLineNumber < 1 || startLineNumber > lineCount) {
309
+ throw new Error('Illegal value for startLineNumber');
310
+ }
311
+ if (endLineNumber < 1 || endLineNumber > lineCount) {
312
+ throw new Error('Illegal value for endLineNumber');
313
+ }
314
+ const options = this.textModel.getOptions();
315
+ const foldingRules = this.getLanguageConfiguration(this.textModel.getLanguageId()).foldingRules;
316
+ const offSide = Boolean(foldingRules && foldingRules.offSide);
317
+ const result = new Array(endLineNumber - startLineNumber + 1);
318
+ let aboveContentLineIndex = -2; /* -2 is a marker for not having computed it */
319
+ let aboveContentLineIndent = -1;
320
+ let belowContentLineIndex = -2; /* -2 is a marker for not having computed it */
321
+ let belowContentLineIndent = -1;
322
+ for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
323
+ const resultIndex = lineNumber - startLineNumber;
324
+ const currentIndent = this._computeIndentLevel(lineNumber - 1);
325
+ if (currentIndent >= 0) {
326
+ // This line has content (besides whitespace)
327
+ // Use the line's indent
328
+ aboveContentLineIndex = lineNumber - 1;
329
+ aboveContentLineIndent = currentIndent;
330
+ result[resultIndex] = Math.ceil(currentIndent / options.indentSize);
331
+ continue;
332
+ }
333
+ if (aboveContentLineIndex === -2) {
334
+ aboveContentLineIndex = -1;
335
+ aboveContentLineIndent = -1;
336
+ // must find previous line with content
337
+ for (let lineIndex = lineNumber - 2; lineIndex >= 0; lineIndex--) {
338
+ const indent = this._computeIndentLevel(lineIndex);
339
+ if (indent >= 0) {
340
+ aboveContentLineIndex = lineIndex;
341
+ aboveContentLineIndent = indent;
342
+ break;
343
+ }
344
+ }
345
+ }
346
+ if (belowContentLineIndex !== -1 &&
347
+ (belowContentLineIndex === -2 || belowContentLineIndex < lineNumber - 1)) {
348
+ belowContentLineIndex = -1;
349
+ belowContentLineIndent = -1;
350
+ // must find next line with content
351
+ for (let lineIndex = lineNumber; lineIndex < lineCount; lineIndex++) {
352
+ const indent = this._computeIndentLevel(lineIndex);
353
+ if (indent >= 0) {
354
+ belowContentLineIndex = lineIndex;
355
+ belowContentLineIndent = indent;
356
+ break;
357
+ }
358
+ }
359
+ }
360
+ result[resultIndex] = this._getIndentLevelForWhitespaceLine(offSide, aboveContentLineIndent, belowContentLineIndent);
361
+ }
362
+ return result;
363
+ }
364
+ _getIndentLevelForWhitespaceLine(offSide, aboveContentLineIndent, belowContentLineIndent) {
365
+ const options = this.textModel.getOptions();
366
+ if (aboveContentLineIndent === -1 || belowContentLineIndent === -1) {
367
+ // At the top or bottom of the file
368
+ return 0;
369
+ }
370
+ else if (aboveContentLineIndent < belowContentLineIndent) {
371
+ // we are inside the region above
372
+ return 1 + Math.floor(aboveContentLineIndent / options.indentSize);
373
+ }
374
+ else if (aboveContentLineIndent === belowContentLineIndent) {
375
+ // we are in between two regions
376
+ return Math.ceil(belowContentLineIndent / options.indentSize);
377
+ }
378
+ else {
379
+ if (offSide) {
380
+ // same level as region below
381
+ return Math.ceil(belowContentLineIndent / options.indentSize);
382
+ }
383
+ else {
384
+ // we are inside the region that ends below
385
+ return 1 + Math.floor(belowContentLineIndent / options.indentSize);
386
+ }
387
+ }
388
+ }
389
+ }
390
+ export class BracketPairGuidesClassNames {
391
+ constructor() {
392
+ this.activeClassName = 'indent-active';
393
+ }
394
+ getInlineClassName(nestingLevel, nestingLevelOfEqualBracketType, independentColorPoolPerBracketType) {
395
+ return this.getInlineClassNameOfLevel(independentColorPoolPerBracketType ? nestingLevelOfEqualBracketType : nestingLevel);
396
+ }
397
+ getInlineClassNameOfLevel(level) {
398
+ // To support a dynamic amount of colors up to 6 colors,
399
+ // we use a number that is a lcm of all numbers from 1 to 6.
400
+ return `bracket-indent-guide lvl-${level % 30}`;
401
+ }
402
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/indentationGuesser.js ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ class SpacesDiffResult {
6
+ constructor() {
7
+ this.spacesDiff = 0;
8
+ this.looksLikeAlignment = false;
9
+ }
10
+ }
11
+ /**
12
+ * Compute the diff in spaces between two line's indentation.
13
+ */
14
+ function spacesDiff(a, aLength, b, bLength, result) {
15
+ result.spacesDiff = 0;
16
+ result.looksLikeAlignment = false;
17
+ // This can go both ways (e.g.):
18
+ // - a: "\t"
19
+ // - b: "\t "
20
+ // => This should count 1 tab and 4 spaces
21
+ let i;
22
+ for (i = 0; i < aLength && i < bLength; i++) {
23
+ const aCharCode = a.charCodeAt(i);
24
+ const bCharCode = b.charCodeAt(i);
25
+ if (aCharCode !== bCharCode) {
26
+ break;
27
+ }
28
+ }
29
+ let aSpacesCnt = 0, aTabsCount = 0;
30
+ for (let j = i; j < aLength; j++) {
31
+ const aCharCode = a.charCodeAt(j);
32
+ if (aCharCode === 32 /* CharCode.Space */) {
33
+ aSpacesCnt++;
34
+ }
35
+ else {
36
+ aTabsCount++;
37
+ }
38
+ }
39
+ let bSpacesCnt = 0, bTabsCount = 0;
40
+ for (let j = i; j < bLength; j++) {
41
+ const bCharCode = b.charCodeAt(j);
42
+ if (bCharCode === 32 /* CharCode.Space */) {
43
+ bSpacesCnt++;
44
+ }
45
+ else {
46
+ bTabsCount++;
47
+ }
48
+ }
49
+ if (aSpacesCnt > 0 && aTabsCount > 0) {
50
+ return;
51
+ }
52
+ if (bSpacesCnt > 0 && bTabsCount > 0) {
53
+ return;
54
+ }
55
+ const tabsDiff = Math.abs(aTabsCount - bTabsCount);
56
+ const spacesDiff = Math.abs(aSpacesCnt - bSpacesCnt);
57
+ if (tabsDiff === 0) {
58
+ // check if the indentation difference might be caused by alignment reasons
59
+ // sometime folks like to align their code, but this should not be used as a hint
60
+ result.spacesDiff = spacesDiff;
61
+ if (spacesDiff > 0 && 0 <= bSpacesCnt - 1 && bSpacesCnt - 1 < a.length && bSpacesCnt < b.length) {
62
+ if (b.charCodeAt(bSpacesCnt) !== 32 /* CharCode.Space */ && a.charCodeAt(bSpacesCnt - 1) === 32 /* CharCode.Space */) {
63
+ if (a.charCodeAt(a.length - 1) === 44 /* CharCode.Comma */) {
64
+ // This looks like an alignment desire: e.g.
65
+ // const a = b + c,
66
+ // d = b - c;
67
+ result.looksLikeAlignment = true;
68
+ }
69
+ }
70
+ }
71
+ return;
72
+ }
73
+ if (spacesDiff % tabsDiff === 0) {
74
+ result.spacesDiff = spacesDiff / tabsDiff;
75
+ return;
76
+ }
77
+ }
78
+ export function guessIndentation(source, defaultTabSize, defaultInsertSpaces) {
79
+ // Look at most at the first 10k lines
80
+ const linesCount = Math.min(source.getLineCount(), 10000);
81
+ let linesIndentedWithTabsCount = 0; // number of lines that contain at least one tab in indentation
82
+ let linesIndentedWithSpacesCount = 0; // number of lines that contain only spaces in indentation
83
+ let previousLineText = ''; // content of latest line that contained non-whitespace chars
84
+ let previousLineIndentation = 0; // index at which latest line contained the first non-whitespace char
85
+ const ALLOWED_TAB_SIZE_GUESSES = [2, 4, 6, 8, 3, 5, 7]; // prefer even guesses for `tabSize`, limit to [2, 8].
86
+ const MAX_ALLOWED_TAB_SIZE_GUESS = 8; // max(ALLOWED_TAB_SIZE_GUESSES) = 8
87
+ const spacesDiffCount = [0, 0, 0, 0, 0, 0, 0, 0, 0]; // `tabSize` scores
88
+ const tmp = new SpacesDiffResult();
89
+ for (let lineNumber = 1; lineNumber <= linesCount; lineNumber++) {
90
+ const currentLineLength = source.getLineLength(lineNumber);
91
+ const currentLineText = source.getLineContent(lineNumber);
92
+ // if the text buffer is chunk based, so long lines are cons-string, v8 will flattern the string when we check charCode.
93
+ // checking charCode on chunks directly is cheaper.
94
+ const useCurrentLineText = (currentLineLength <= 65536);
95
+ let currentLineHasContent = false; // does `currentLineText` contain non-whitespace chars
96
+ let currentLineIndentation = 0; // index at which `currentLineText` contains the first non-whitespace char
97
+ let currentLineSpacesCount = 0; // count of spaces found in `currentLineText` indentation
98
+ let currentLineTabsCount = 0; // count of tabs found in `currentLineText` indentation
99
+ for (let j = 0, lenJ = currentLineLength; j < lenJ; j++) {
100
+ const charCode = (useCurrentLineText ? currentLineText.charCodeAt(j) : source.getLineCharCode(lineNumber, j));
101
+ if (charCode === 9 /* CharCode.Tab */) {
102
+ currentLineTabsCount++;
103
+ }
104
+ else if (charCode === 32 /* CharCode.Space */) {
105
+ currentLineSpacesCount++;
106
+ }
107
+ else {
108
+ // Hit non whitespace character on this line
109
+ currentLineHasContent = true;
110
+ currentLineIndentation = j;
111
+ break;
112
+ }
113
+ }
114
+ // Ignore empty or only whitespace lines
115
+ if (!currentLineHasContent) {
116
+ continue;
117
+ }
118
+ if (currentLineTabsCount > 0) {
119
+ linesIndentedWithTabsCount++;
120
+ }
121
+ else if (currentLineSpacesCount > 1) {
122
+ linesIndentedWithSpacesCount++;
123
+ }
124
+ spacesDiff(previousLineText, previousLineIndentation, currentLineText, currentLineIndentation, tmp);
125
+ if (tmp.looksLikeAlignment) {
126
+ // if defaultInsertSpaces === true && the spaces count == tabSize, we may want to count it as valid indentation
127
+ //
128
+ // - item1
129
+ // - item2
130
+ //
131
+ // otherwise skip this line entirely
132
+ //
133
+ // const a = 1,
134
+ // b = 2;
135
+ if (!(defaultInsertSpaces && defaultTabSize === tmp.spacesDiff)) {
136
+ continue;
137
+ }
138
+ }
139
+ const currentSpacesDiff = tmp.spacesDiff;
140
+ if (currentSpacesDiff <= MAX_ALLOWED_TAB_SIZE_GUESS) {
141
+ spacesDiffCount[currentSpacesDiff]++;
142
+ }
143
+ previousLineText = currentLineText;
144
+ previousLineIndentation = currentLineIndentation;
145
+ }
146
+ let insertSpaces = defaultInsertSpaces;
147
+ if (linesIndentedWithTabsCount !== linesIndentedWithSpacesCount) {
148
+ insertSpaces = (linesIndentedWithTabsCount < linesIndentedWithSpacesCount);
149
+ }
150
+ let tabSize = defaultTabSize;
151
+ // Guess tabSize only if inserting spaces...
152
+ if (insertSpaces) {
153
+ let tabSizeScore = (insertSpaces ? 0 : 0.1 * linesCount);
154
+ // console.log("score threshold: " + tabSizeScore);
155
+ ALLOWED_TAB_SIZE_GUESSES.forEach((possibleTabSize) => {
156
+ const possibleTabSizeScore = spacesDiffCount[possibleTabSize];
157
+ if (possibleTabSizeScore > tabSizeScore) {
158
+ tabSizeScore = possibleTabSizeScore;
159
+ tabSize = possibleTabSize;
160
+ }
161
+ });
162
+ // Let a tabSize of 2 win even if it is not the maximum
163
+ // (only in case 4 was guessed)
164
+ if (tabSize === 4 && spacesDiffCount[4] > 0 && spacesDiffCount[2] > 0 && spacesDiffCount[2] >= spacesDiffCount[4] / 2) {
165
+ tabSize = 2;
166
+ }
167
+ }
168
+ // console.log('--------------------------');
169
+ // console.log('linesIndentedWithTabsCount: ' + linesIndentedWithTabsCount + ', linesIndentedWithSpacesCount: ' + linesIndentedWithSpacesCount);
170
+ // console.log('spacesDiffCount: ' + spacesDiffCount);
171
+ // console.log('tabSize: ' + tabSize + ', tabSizeScore: ' + tabSizeScore);
172
+ return {
173
+ insertSpaces: insertSpaces,
174
+ tabSize: tabSize
175
+ };
176
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/intervalTree.js ADDED
@@ -0,0 +1,986 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export function getNodeColor(node) {
6
+ return ((node.metadata & 1 /* Constants.ColorMask */) >>> 0 /* Constants.ColorOffset */);
7
+ }
8
+ function setNodeColor(node, color) {
9
+ node.metadata = ((node.metadata & 254 /* Constants.ColorMaskInverse */) | (color << 0 /* Constants.ColorOffset */));
10
+ }
11
+ function getNodeIsVisited(node) {
12
+ return ((node.metadata & 2 /* Constants.IsVisitedMask */) >>> 1 /* Constants.IsVisitedOffset */) === 1;
13
+ }
14
+ function setNodeIsVisited(node, value) {
15
+ node.metadata = ((node.metadata & 253 /* Constants.IsVisitedMaskInverse */) | ((value ? 1 : 0) << 1 /* Constants.IsVisitedOffset */));
16
+ }
17
+ function getNodeIsForValidation(node) {
18
+ return ((node.metadata & 4 /* Constants.IsForValidationMask */) >>> 2 /* Constants.IsForValidationOffset */) === 1;
19
+ }
20
+ function setNodeIsForValidation(node, value) {
21
+ node.metadata = ((node.metadata & 251 /* Constants.IsForValidationMaskInverse */) | ((value ? 1 : 0) << 2 /* Constants.IsForValidationOffset */));
22
+ }
23
+ function getNodeIsInGlyphMargin(node) {
24
+ return ((node.metadata & 64 /* Constants.IsMarginMask */) >>> 6 /* Constants.IsMarginOffset */) === 1;
25
+ }
26
+ function setNodeIsInGlyphMargin(node, value) {
27
+ node.metadata = ((node.metadata & 191 /* Constants.IsMarginMaskInverse */) | ((value ? 1 : 0) << 6 /* Constants.IsMarginOffset */));
28
+ }
29
+ function getNodeStickiness(node) {
30
+ return ((node.metadata & 24 /* Constants.StickinessMask */) >>> 3 /* Constants.StickinessOffset */);
31
+ }
32
+ function _setNodeStickiness(node, stickiness) {
33
+ node.metadata = ((node.metadata & 231 /* Constants.StickinessMaskInverse */) | (stickiness << 3 /* Constants.StickinessOffset */));
34
+ }
35
+ function getCollapseOnReplaceEdit(node) {
36
+ return ((node.metadata & 32 /* Constants.CollapseOnReplaceEditMask */) >>> 5 /* Constants.CollapseOnReplaceEditOffset */) === 1;
37
+ }
38
+ function setCollapseOnReplaceEdit(node, value) {
39
+ node.metadata = ((node.metadata & 223 /* Constants.CollapseOnReplaceEditMaskInverse */) | ((value ? 1 : 0) << 5 /* Constants.CollapseOnReplaceEditOffset */));
40
+ }
41
+ export class IntervalNode {
42
+ constructor(id, start, end) {
43
+ this.metadata = 0;
44
+ this.parent = this;
45
+ this.left = this;
46
+ this.right = this;
47
+ setNodeColor(this, 1 /* NodeColor.Red */);
48
+ this.start = start;
49
+ this.end = end;
50
+ // FORCE_OVERFLOWING_TEST: this.delta = start;
51
+ this.delta = 0;
52
+ this.maxEnd = end;
53
+ this.id = id;
54
+ this.ownerId = 0;
55
+ this.options = null;
56
+ setNodeIsForValidation(this, false);
57
+ setNodeIsInGlyphMargin(this, false);
58
+ _setNodeStickiness(this, 1 /* TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */);
59
+ setCollapseOnReplaceEdit(this, false);
60
+ this.cachedVersionId = 0;
61
+ this.cachedAbsoluteStart = start;
62
+ this.cachedAbsoluteEnd = end;
63
+ this.range = null;
64
+ setNodeIsVisited(this, false);
65
+ }
66
+ reset(versionId, start, end, range) {
67
+ this.start = start;
68
+ this.end = end;
69
+ this.maxEnd = end;
70
+ this.cachedVersionId = versionId;
71
+ this.cachedAbsoluteStart = start;
72
+ this.cachedAbsoluteEnd = end;
73
+ this.range = range;
74
+ }
75
+ setOptions(options) {
76
+ this.options = options;
77
+ const className = this.options.className;
78
+ setNodeIsForValidation(this, (className === "squiggly-error" /* ClassName.EditorErrorDecoration */
79
+ || className === "squiggly-warning" /* ClassName.EditorWarningDecoration */
80
+ || className === "squiggly-info" /* ClassName.EditorInfoDecoration */));
81
+ setNodeIsInGlyphMargin(this, this.options.glyphMarginClassName !== null);
82
+ _setNodeStickiness(this, this.options.stickiness);
83
+ setCollapseOnReplaceEdit(this, this.options.collapseOnReplaceEdit);
84
+ }
85
+ setCachedOffsets(absoluteStart, absoluteEnd, cachedVersionId) {
86
+ if (this.cachedVersionId !== cachedVersionId) {
87
+ this.range = null;
88
+ }
89
+ this.cachedVersionId = cachedVersionId;
90
+ this.cachedAbsoluteStart = absoluteStart;
91
+ this.cachedAbsoluteEnd = absoluteEnd;
92
+ }
93
+ detach() {
94
+ this.parent = null;
95
+ this.left = null;
96
+ this.right = null;
97
+ }
98
+ }
99
+ export const SENTINEL = new IntervalNode(null, 0, 0);
100
+ SENTINEL.parent = SENTINEL;
101
+ SENTINEL.left = SENTINEL;
102
+ SENTINEL.right = SENTINEL;
103
+ setNodeColor(SENTINEL, 0 /* NodeColor.Black */);
104
+ export class IntervalTree {
105
+ constructor() {
106
+ this.root = SENTINEL;
107
+ this.requestNormalizeDelta = false;
108
+ }
109
+ intervalSearch(start, end, filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations) {
110
+ if (this.root === SENTINEL) {
111
+ return [];
112
+ }
113
+ return intervalSearch(this, start, end, filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations);
114
+ }
115
+ search(filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations) {
116
+ if (this.root === SENTINEL) {
117
+ return [];
118
+ }
119
+ return search(this, filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations);
120
+ }
121
+ /**
122
+ * Will not set `cachedAbsoluteStart` nor `cachedAbsoluteEnd` on the returned nodes!
123
+ */
124
+ collectNodesFromOwner(ownerId) {
125
+ return collectNodesFromOwner(this, ownerId);
126
+ }
127
+ /**
128
+ * Will not set `cachedAbsoluteStart` nor `cachedAbsoluteEnd` on the returned nodes!
129
+ */
130
+ collectNodesPostOrder() {
131
+ return collectNodesPostOrder(this);
132
+ }
133
+ insert(node) {
134
+ rbTreeInsert(this, node);
135
+ this._normalizeDeltaIfNecessary();
136
+ }
137
+ delete(node) {
138
+ rbTreeDelete(this, node);
139
+ this._normalizeDeltaIfNecessary();
140
+ }
141
+ resolveNode(node, cachedVersionId) {
142
+ const initialNode = node;
143
+ let delta = 0;
144
+ while (node !== this.root) {
145
+ if (node === node.parent.right) {
146
+ delta += node.parent.delta;
147
+ }
148
+ node = node.parent;
149
+ }
150
+ const nodeStart = initialNode.start + delta;
151
+ const nodeEnd = initialNode.end + delta;
152
+ initialNode.setCachedOffsets(nodeStart, nodeEnd, cachedVersionId);
153
+ }
154
+ acceptReplace(offset, length, textLength, forceMoveMarkers) {
155
+ // Our strategy is to remove all directly impacted nodes, and then add them back to the tree.
156
+ // (1) collect all nodes that are intersecting this edit as nodes of interest
157
+ const nodesOfInterest = searchForEditing(this, offset, offset + length);
158
+ // (2) remove all nodes that are intersecting this edit
159
+ for (let i = 0, len = nodesOfInterest.length; i < len; i++) {
160
+ const node = nodesOfInterest[i];
161
+ rbTreeDelete(this, node);
162
+ }
163
+ this._normalizeDeltaIfNecessary();
164
+ // (3) edit all tree nodes except the nodes of interest
165
+ noOverlapReplace(this, offset, offset + length, textLength);
166
+ this._normalizeDeltaIfNecessary();
167
+ // (4) edit the nodes of interest and insert them back in the tree
168
+ for (let i = 0, len = nodesOfInterest.length; i < len; i++) {
169
+ const node = nodesOfInterest[i];
170
+ node.start = node.cachedAbsoluteStart;
171
+ node.end = node.cachedAbsoluteEnd;
172
+ nodeAcceptEdit(node, offset, (offset + length), textLength, forceMoveMarkers);
173
+ node.maxEnd = node.end;
174
+ rbTreeInsert(this, node);
175
+ }
176
+ this._normalizeDeltaIfNecessary();
177
+ }
178
+ _normalizeDeltaIfNecessary() {
179
+ if (!this.requestNormalizeDelta) {
180
+ return;
181
+ }
182
+ this.requestNormalizeDelta = false;
183
+ normalizeDelta(this);
184
+ }
185
+ }
186
+ //#region Delta Normalization
187
+ function normalizeDelta(T) {
188
+ let node = T.root;
189
+ let delta = 0;
190
+ while (node !== SENTINEL) {
191
+ if (node.left !== SENTINEL && !getNodeIsVisited(node.left)) {
192
+ // go left
193
+ node = node.left;
194
+ continue;
195
+ }
196
+ if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
197
+ // go right
198
+ delta += node.delta;
199
+ node = node.right;
200
+ continue;
201
+ }
202
+ // handle current node
203
+ node.start = delta + node.start;
204
+ node.end = delta + node.end;
205
+ node.delta = 0;
206
+ recomputeMaxEnd(node);
207
+ setNodeIsVisited(node, true);
208
+ // going up from this node
209
+ setNodeIsVisited(node.left, false);
210
+ setNodeIsVisited(node.right, false);
211
+ if (node === node.parent.right) {
212
+ delta -= node.parent.delta;
213
+ }
214
+ node = node.parent;
215
+ }
216
+ setNodeIsVisited(T.root, false);
217
+ }
218
+ function adjustMarkerBeforeColumn(markerOffset, markerStickToPreviousCharacter, checkOffset, moveSemantics) {
219
+ if (markerOffset < checkOffset) {
220
+ return true;
221
+ }
222
+ if (markerOffset > checkOffset) {
223
+ return false;
224
+ }
225
+ if (moveSemantics === 1 /* MarkerMoveSemantics.ForceMove */) {
226
+ return false;
227
+ }
228
+ if (moveSemantics === 2 /* MarkerMoveSemantics.ForceStay */) {
229
+ return true;
230
+ }
231
+ return markerStickToPreviousCharacter;
232
+ }
233
+ /**
234
+ * This is a lot more complicated than strictly necessary to maintain the same behaviour
235
+ * as when decorations were implemented using two markers.
236
+ */
237
+ export function nodeAcceptEdit(node, start, end, textLength, forceMoveMarkers) {
238
+ const nodeStickiness = getNodeStickiness(node);
239
+ const startStickToPreviousCharacter = (nodeStickiness === 0 /* TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges */
240
+ || nodeStickiness === 2 /* TrackedRangeStickiness.GrowsOnlyWhenTypingBefore */);
241
+ const endStickToPreviousCharacter = (nodeStickiness === 1 /* TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */
242
+ || nodeStickiness === 2 /* TrackedRangeStickiness.GrowsOnlyWhenTypingBefore */);
243
+ const deletingCnt = (end - start);
244
+ const insertingCnt = textLength;
245
+ const commonLength = Math.min(deletingCnt, insertingCnt);
246
+ const nodeStart = node.start;
247
+ let startDone = false;
248
+ const nodeEnd = node.end;
249
+ let endDone = false;
250
+ if (start <= nodeStart && nodeEnd <= end && getCollapseOnReplaceEdit(node)) {
251
+ // This edit encompasses the entire decoration range
252
+ // and the decoration has asked to become collapsed
253
+ node.start = start;
254
+ startDone = true;
255
+ node.end = start;
256
+ endDone = true;
257
+ }
258
+ {
259
+ const moveSemantics = forceMoveMarkers ? 1 /* MarkerMoveSemantics.ForceMove */ : (deletingCnt > 0 ? 2 /* MarkerMoveSemantics.ForceStay */ : 0 /* MarkerMoveSemantics.MarkerDefined */);
260
+ if (!startDone && adjustMarkerBeforeColumn(nodeStart, startStickToPreviousCharacter, start, moveSemantics)) {
261
+ startDone = true;
262
+ }
263
+ if (!endDone && adjustMarkerBeforeColumn(nodeEnd, endStickToPreviousCharacter, start, moveSemantics)) {
264
+ endDone = true;
265
+ }
266
+ }
267
+ if (commonLength > 0 && !forceMoveMarkers) {
268
+ const moveSemantics = (deletingCnt > insertingCnt ? 2 /* MarkerMoveSemantics.ForceStay */ : 0 /* MarkerMoveSemantics.MarkerDefined */);
269
+ if (!startDone && adjustMarkerBeforeColumn(nodeStart, startStickToPreviousCharacter, start + commonLength, moveSemantics)) {
270
+ startDone = true;
271
+ }
272
+ if (!endDone && adjustMarkerBeforeColumn(nodeEnd, endStickToPreviousCharacter, start + commonLength, moveSemantics)) {
273
+ endDone = true;
274
+ }
275
+ }
276
+ {
277
+ const moveSemantics = forceMoveMarkers ? 1 /* MarkerMoveSemantics.ForceMove */ : 0 /* MarkerMoveSemantics.MarkerDefined */;
278
+ if (!startDone && adjustMarkerBeforeColumn(nodeStart, startStickToPreviousCharacter, end, moveSemantics)) {
279
+ node.start = start + insertingCnt;
280
+ startDone = true;
281
+ }
282
+ if (!endDone && adjustMarkerBeforeColumn(nodeEnd, endStickToPreviousCharacter, end, moveSemantics)) {
283
+ node.end = start + insertingCnt;
284
+ endDone = true;
285
+ }
286
+ }
287
+ // Finish
288
+ const deltaColumn = (insertingCnt - deletingCnt);
289
+ if (!startDone) {
290
+ node.start = Math.max(0, nodeStart + deltaColumn);
291
+ }
292
+ if (!endDone) {
293
+ node.end = Math.max(0, nodeEnd + deltaColumn);
294
+ }
295
+ if (node.start > node.end) {
296
+ node.end = node.start;
297
+ }
298
+ }
299
+ function searchForEditing(T, start, end) {
300
+ // https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree
301
+ // Now, it is known that two intervals A and B overlap only when both
302
+ // A.low <= B.high and A.high >= B.low. When searching the trees for
303
+ // nodes overlapping with a given interval, you can immediately skip:
304
+ // a) all nodes to the right of nodes whose low value is past the end of the given interval.
305
+ // b) all nodes that have their maximum 'high' value below the start of the given interval.
306
+ let node = T.root;
307
+ let delta = 0;
308
+ let nodeMaxEnd = 0;
309
+ let nodeStart = 0;
310
+ let nodeEnd = 0;
311
+ const result = [];
312
+ let resultLen = 0;
313
+ while (node !== SENTINEL) {
314
+ if (getNodeIsVisited(node)) {
315
+ // going up from this node
316
+ setNodeIsVisited(node.left, false);
317
+ setNodeIsVisited(node.right, false);
318
+ if (node === node.parent.right) {
319
+ delta -= node.parent.delta;
320
+ }
321
+ node = node.parent;
322
+ continue;
323
+ }
324
+ if (!getNodeIsVisited(node.left)) {
325
+ // first time seeing this node
326
+ nodeMaxEnd = delta + node.maxEnd;
327
+ if (nodeMaxEnd < start) {
328
+ // cover case b) from above
329
+ // there is no need to search this node or its children
330
+ setNodeIsVisited(node, true);
331
+ continue;
332
+ }
333
+ if (node.left !== SENTINEL) {
334
+ // go left
335
+ node = node.left;
336
+ continue;
337
+ }
338
+ }
339
+ // handle current node
340
+ nodeStart = delta + node.start;
341
+ if (nodeStart > end) {
342
+ // cover case a) from above
343
+ // there is no need to search this node or its right subtree
344
+ setNodeIsVisited(node, true);
345
+ continue;
346
+ }
347
+ nodeEnd = delta + node.end;
348
+ if (nodeEnd >= start) {
349
+ node.setCachedOffsets(nodeStart, nodeEnd, 0);
350
+ result[resultLen++] = node;
351
+ }
352
+ setNodeIsVisited(node, true);
353
+ if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
354
+ // go right
355
+ delta += node.delta;
356
+ node = node.right;
357
+ continue;
358
+ }
359
+ }
360
+ setNodeIsVisited(T.root, false);
361
+ return result;
362
+ }
363
+ function noOverlapReplace(T, start, end, textLength) {
364
+ // https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree
365
+ // Now, it is known that two intervals A and B overlap only when both
366
+ // A.low <= B.high and A.high >= B.low. When searching the trees for
367
+ // nodes overlapping with a given interval, you can immediately skip:
368
+ // a) all nodes to the right of nodes whose low value is past the end of the given interval.
369
+ // b) all nodes that have their maximum 'high' value below the start of the given interval.
370
+ let node = T.root;
371
+ let delta = 0;
372
+ let nodeMaxEnd = 0;
373
+ let nodeStart = 0;
374
+ const editDelta = (textLength - (end - start));
375
+ while (node !== SENTINEL) {
376
+ if (getNodeIsVisited(node)) {
377
+ // going up from this node
378
+ setNodeIsVisited(node.left, false);
379
+ setNodeIsVisited(node.right, false);
380
+ if (node === node.parent.right) {
381
+ delta -= node.parent.delta;
382
+ }
383
+ recomputeMaxEnd(node);
384
+ node = node.parent;
385
+ continue;
386
+ }
387
+ if (!getNodeIsVisited(node.left)) {
388
+ // first time seeing this node
389
+ nodeMaxEnd = delta + node.maxEnd;
390
+ if (nodeMaxEnd < start) {
391
+ // cover case b) from above
392
+ // there is no need to search this node or its children
393
+ setNodeIsVisited(node, true);
394
+ continue;
395
+ }
396
+ if (node.left !== SENTINEL) {
397
+ // go left
398
+ node = node.left;
399
+ continue;
400
+ }
401
+ }
402
+ // handle current node
403
+ nodeStart = delta + node.start;
404
+ if (nodeStart > end) {
405
+ node.start += editDelta;
406
+ node.end += editDelta;
407
+ node.delta += editDelta;
408
+ if (node.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || node.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
409
+ T.requestNormalizeDelta = true;
410
+ }
411
+ // cover case a) from above
412
+ // there is no need to search this node or its right subtree
413
+ setNodeIsVisited(node, true);
414
+ continue;
415
+ }
416
+ setNodeIsVisited(node, true);
417
+ if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
418
+ // go right
419
+ delta += node.delta;
420
+ node = node.right;
421
+ continue;
422
+ }
423
+ }
424
+ setNodeIsVisited(T.root, false);
425
+ }
426
+ //#endregion
427
+ //#region Searching
428
+ function collectNodesFromOwner(T, ownerId) {
429
+ let node = T.root;
430
+ const result = [];
431
+ let resultLen = 0;
432
+ while (node !== SENTINEL) {
433
+ if (getNodeIsVisited(node)) {
434
+ // going up from this node
435
+ setNodeIsVisited(node.left, false);
436
+ setNodeIsVisited(node.right, false);
437
+ node = node.parent;
438
+ continue;
439
+ }
440
+ if (node.left !== SENTINEL && !getNodeIsVisited(node.left)) {
441
+ // go left
442
+ node = node.left;
443
+ continue;
444
+ }
445
+ // handle current node
446
+ if (node.ownerId === ownerId) {
447
+ result[resultLen++] = node;
448
+ }
449
+ setNodeIsVisited(node, true);
450
+ if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
451
+ // go right
452
+ node = node.right;
453
+ continue;
454
+ }
455
+ }
456
+ setNodeIsVisited(T.root, false);
457
+ return result;
458
+ }
459
+ function collectNodesPostOrder(T) {
460
+ let node = T.root;
461
+ const result = [];
462
+ let resultLen = 0;
463
+ while (node !== SENTINEL) {
464
+ if (getNodeIsVisited(node)) {
465
+ // going up from this node
466
+ setNodeIsVisited(node.left, false);
467
+ setNodeIsVisited(node.right, false);
468
+ node = node.parent;
469
+ continue;
470
+ }
471
+ if (node.left !== SENTINEL && !getNodeIsVisited(node.left)) {
472
+ // go left
473
+ node = node.left;
474
+ continue;
475
+ }
476
+ if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
477
+ // go right
478
+ node = node.right;
479
+ continue;
480
+ }
481
+ // handle current node
482
+ result[resultLen++] = node;
483
+ setNodeIsVisited(node, true);
484
+ }
485
+ setNodeIsVisited(T.root, false);
486
+ return result;
487
+ }
488
+ function search(T, filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations) {
489
+ let node = T.root;
490
+ let delta = 0;
491
+ let nodeStart = 0;
492
+ let nodeEnd = 0;
493
+ const result = [];
494
+ let resultLen = 0;
495
+ while (node !== SENTINEL) {
496
+ if (getNodeIsVisited(node)) {
497
+ // going up from this node
498
+ setNodeIsVisited(node.left, false);
499
+ setNodeIsVisited(node.right, false);
500
+ if (node === node.parent.right) {
501
+ delta -= node.parent.delta;
502
+ }
503
+ node = node.parent;
504
+ continue;
505
+ }
506
+ if (node.left !== SENTINEL && !getNodeIsVisited(node.left)) {
507
+ // go left
508
+ node = node.left;
509
+ continue;
510
+ }
511
+ // handle current node
512
+ nodeStart = delta + node.start;
513
+ nodeEnd = delta + node.end;
514
+ node.setCachedOffsets(nodeStart, nodeEnd, cachedVersionId);
515
+ let include = true;
516
+ if (filterOwnerId && node.ownerId && node.ownerId !== filterOwnerId) {
517
+ include = false;
518
+ }
519
+ if (filterOutValidation && getNodeIsForValidation(node)) {
520
+ include = false;
521
+ }
522
+ if (onlyMarginDecorations && !getNodeIsInGlyphMargin(node)) {
523
+ include = false;
524
+ }
525
+ if (include) {
526
+ result[resultLen++] = node;
527
+ }
528
+ setNodeIsVisited(node, true);
529
+ if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
530
+ // go right
531
+ delta += node.delta;
532
+ node = node.right;
533
+ continue;
534
+ }
535
+ }
536
+ setNodeIsVisited(T.root, false);
537
+ return result;
538
+ }
539
+ function intervalSearch(T, intervalStart, intervalEnd, filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations) {
540
+ // https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree
541
+ // Now, it is known that two intervals A and B overlap only when both
542
+ // A.low <= B.high and A.high >= B.low. When searching the trees for
543
+ // nodes overlapping with a given interval, you can immediately skip:
544
+ // a) all nodes to the right of nodes whose low value is past the end of the given interval.
545
+ // b) all nodes that have their maximum 'high' value below the start of the given interval.
546
+ let node = T.root;
547
+ let delta = 0;
548
+ let nodeMaxEnd = 0;
549
+ let nodeStart = 0;
550
+ let nodeEnd = 0;
551
+ const result = [];
552
+ let resultLen = 0;
553
+ while (node !== SENTINEL) {
554
+ if (getNodeIsVisited(node)) {
555
+ // going up from this node
556
+ setNodeIsVisited(node.left, false);
557
+ setNodeIsVisited(node.right, false);
558
+ if (node === node.parent.right) {
559
+ delta -= node.parent.delta;
560
+ }
561
+ node = node.parent;
562
+ continue;
563
+ }
564
+ if (!getNodeIsVisited(node.left)) {
565
+ // first time seeing this node
566
+ nodeMaxEnd = delta + node.maxEnd;
567
+ if (nodeMaxEnd < intervalStart) {
568
+ // cover case b) from above
569
+ // there is no need to search this node or its children
570
+ setNodeIsVisited(node, true);
571
+ continue;
572
+ }
573
+ if (node.left !== SENTINEL) {
574
+ // go left
575
+ node = node.left;
576
+ continue;
577
+ }
578
+ }
579
+ // handle current node
580
+ nodeStart = delta + node.start;
581
+ if (nodeStart > intervalEnd) {
582
+ // cover case a) from above
583
+ // there is no need to search this node or its right subtree
584
+ setNodeIsVisited(node, true);
585
+ continue;
586
+ }
587
+ nodeEnd = delta + node.end;
588
+ if (nodeEnd >= intervalStart) {
589
+ // There is overlap
590
+ node.setCachedOffsets(nodeStart, nodeEnd, cachedVersionId);
591
+ let include = true;
592
+ if (filterOwnerId && node.ownerId && node.ownerId !== filterOwnerId) {
593
+ include = false;
594
+ }
595
+ if (filterOutValidation && getNodeIsForValidation(node)) {
596
+ include = false;
597
+ }
598
+ if (onlyMarginDecorations && !getNodeIsInGlyphMargin(node)) {
599
+ include = false;
600
+ }
601
+ if (include) {
602
+ result[resultLen++] = node;
603
+ }
604
+ }
605
+ setNodeIsVisited(node, true);
606
+ if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
607
+ // go right
608
+ delta += node.delta;
609
+ node = node.right;
610
+ continue;
611
+ }
612
+ }
613
+ setNodeIsVisited(T.root, false);
614
+ return result;
615
+ }
616
+ //#endregion
617
+ //#region Insertion
618
+ function rbTreeInsert(T, newNode) {
619
+ if (T.root === SENTINEL) {
620
+ newNode.parent = SENTINEL;
621
+ newNode.left = SENTINEL;
622
+ newNode.right = SENTINEL;
623
+ setNodeColor(newNode, 0 /* NodeColor.Black */);
624
+ T.root = newNode;
625
+ return T.root;
626
+ }
627
+ treeInsert(T, newNode);
628
+ recomputeMaxEndWalkToRoot(newNode.parent);
629
+ // repair tree
630
+ let x = newNode;
631
+ while (x !== T.root && getNodeColor(x.parent) === 1 /* NodeColor.Red */) {
632
+ if (x.parent === x.parent.parent.left) {
633
+ const y = x.parent.parent.right;
634
+ if (getNodeColor(y) === 1 /* NodeColor.Red */) {
635
+ setNodeColor(x.parent, 0 /* NodeColor.Black */);
636
+ setNodeColor(y, 0 /* NodeColor.Black */);
637
+ setNodeColor(x.parent.parent, 1 /* NodeColor.Red */);
638
+ x = x.parent.parent;
639
+ }
640
+ else {
641
+ if (x === x.parent.right) {
642
+ x = x.parent;
643
+ leftRotate(T, x);
644
+ }
645
+ setNodeColor(x.parent, 0 /* NodeColor.Black */);
646
+ setNodeColor(x.parent.parent, 1 /* NodeColor.Red */);
647
+ rightRotate(T, x.parent.parent);
648
+ }
649
+ }
650
+ else {
651
+ const y = x.parent.parent.left;
652
+ if (getNodeColor(y) === 1 /* NodeColor.Red */) {
653
+ setNodeColor(x.parent, 0 /* NodeColor.Black */);
654
+ setNodeColor(y, 0 /* NodeColor.Black */);
655
+ setNodeColor(x.parent.parent, 1 /* NodeColor.Red */);
656
+ x = x.parent.parent;
657
+ }
658
+ else {
659
+ if (x === x.parent.left) {
660
+ x = x.parent;
661
+ rightRotate(T, x);
662
+ }
663
+ setNodeColor(x.parent, 0 /* NodeColor.Black */);
664
+ setNodeColor(x.parent.parent, 1 /* NodeColor.Red */);
665
+ leftRotate(T, x.parent.parent);
666
+ }
667
+ }
668
+ }
669
+ setNodeColor(T.root, 0 /* NodeColor.Black */);
670
+ return newNode;
671
+ }
672
+ function treeInsert(T, z) {
673
+ let delta = 0;
674
+ let x = T.root;
675
+ const zAbsoluteStart = z.start;
676
+ const zAbsoluteEnd = z.end;
677
+ while (true) {
678
+ const cmp = intervalCompare(zAbsoluteStart, zAbsoluteEnd, x.start + delta, x.end + delta);
679
+ if (cmp < 0) {
680
+ // this node should be inserted to the left
681
+ // => it is not affected by the node's delta
682
+ if (x.left === SENTINEL) {
683
+ z.start -= delta;
684
+ z.end -= delta;
685
+ z.maxEnd -= delta;
686
+ x.left = z;
687
+ break;
688
+ }
689
+ else {
690
+ x = x.left;
691
+ }
692
+ }
693
+ else {
694
+ // this node should be inserted to the right
695
+ // => it is not affected by the node's delta
696
+ if (x.right === SENTINEL) {
697
+ z.start -= (delta + x.delta);
698
+ z.end -= (delta + x.delta);
699
+ z.maxEnd -= (delta + x.delta);
700
+ x.right = z;
701
+ break;
702
+ }
703
+ else {
704
+ delta += x.delta;
705
+ x = x.right;
706
+ }
707
+ }
708
+ }
709
+ z.parent = x;
710
+ z.left = SENTINEL;
711
+ z.right = SENTINEL;
712
+ setNodeColor(z, 1 /* NodeColor.Red */);
713
+ }
714
+ //#endregion
715
+ //#region Deletion
716
+ function rbTreeDelete(T, z) {
717
+ let x;
718
+ let y;
719
+ // RB-DELETE except we don't swap z and y in case c)
720
+ // i.e. we always delete what's pointed at by z.
721
+ if (z.left === SENTINEL) {
722
+ x = z.right;
723
+ y = z;
724
+ // x's delta is no longer influenced by z's delta
725
+ x.delta += z.delta;
726
+ if (x.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || x.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
727
+ T.requestNormalizeDelta = true;
728
+ }
729
+ x.start += z.delta;
730
+ x.end += z.delta;
731
+ }
732
+ else if (z.right === SENTINEL) {
733
+ x = z.left;
734
+ y = z;
735
+ }
736
+ else {
737
+ y = leftest(z.right);
738
+ x = y.right;
739
+ // y's delta is no longer influenced by z's delta,
740
+ // but we don't want to walk the entire right-hand-side subtree of x.
741
+ // we therefore maintain z's delta in y, and adjust only x
742
+ x.start += y.delta;
743
+ x.end += y.delta;
744
+ x.delta += y.delta;
745
+ if (x.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || x.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
746
+ T.requestNormalizeDelta = true;
747
+ }
748
+ y.start += z.delta;
749
+ y.end += z.delta;
750
+ y.delta = z.delta;
751
+ if (y.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || y.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
752
+ T.requestNormalizeDelta = true;
753
+ }
754
+ }
755
+ if (y === T.root) {
756
+ T.root = x;
757
+ setNodeColor(x, 0 /* NodeColor.Black */);
758
+ z.detach();
759
+ resetSentinel();
760
+ recomputeMaxEnd(x);
761
+ T.root.parent = SENTINEL;
762
+ return;
763
+ }
764
+ const yWasRed = (getNodeColor(y) === 1 /* NodeColor.Red */);
765
+ if (y === y.parent.left) {
766
+ y.parent.left = x;
767
+ }
768
+ else {
769
+ y.parent.right = x;
770
+ }
771
+ if (y === z) {
772
+ x.parent = y.parent;
773
+ }
774
+ else {
775
+ if (y.parent === z) {
776
+ x.parent = y;
777
+ }
778
+ else {
779
+ x.parent = y.parent;
780
+ }
781
+ y.left = z.left;
782
+ y.right = z.right;
783
+ y.parent = z.parent;
784
+ setNodeColor(y, getNodeColor(z));
785
+ if (z === T.root) {
786
+ T.root = y;
787
+ }
788
+ else {
789
+ if (z === z.parent.left) {
790
+ z.parent.left = y;
791
+ }
792
+ else {
793
+ z.parent.right = y;
794
+ }
795
+ }
796
+ if (y.left !== SENTINEL) {
797
+ y.left.parent = y;
798
+ }
799
+ if (y.right !== SENTINEL) {
800
+ y.right.parent = y;
801
+ }
802
+ }
803
+ z.detach();
804
+ if (yWasRed) {
805
+ recomputeMaxEndWalkToRoot(x.parent);
806
+ if (y !== z) {
807
+ recomputeMaxEndWalkToRoot(y);
808
+ recomputeMaxEndWalkToRoot(y.parent);
809
+ }
810
+ resetSentinel();
811
+ return;
812
+ }
813
+ recomputeMaxEndWalkToRoot(x);
814
+ recomputeMaxEndWalkToRoot(x.parent);
815
+ if (y !== z) {
816
+ recomputeMaxEndWalkToRoot(y);
817
+ recomputeMaxEndWalkToRoot(y.parent);
818
+ }
819
+ // RB-DELETE-FIXUP
820
+ let w;
821
+ while (x !== T.root && getNodeColor(x) === 0 /* NodeColor.Black */) {
822
+ if (x === x.parent.left) {
823
+ w = x.parent.right;
824
+ if (getNodeColor(w) === 1 /* NodeColor.Red */) {
825
+ setNodeColor(w, 0 /* NodeColor.Black */);
826
+ setNodeColor(x.parent, 1 /* NodeColor.Red */);
827
+ leftRotate(T, x.parent);
828
+ w = x.parent.right;
829
+ }
830
+ if (getNodeColor(w.left) === 0 /* NodeColor.Black */ && getNodeColor(w.right) === 0 /* NodeColor.Black */) {
831
+ setNodeColor(w, 1 /* NodeColor.Red */);
832
+ x = x.parent;
833
+ }
834
+ else {
835
+ if (getNodeColor(w.right) === 0 /* NodeColor.Black */) {
836
+ setNodeColor(w.left, 0 /* NodeColor.Black */);
837
+ setNodeColor(w, 1 /* NodeColor.Red */);
838
+ rightRotate(T, w);
839
+ w = x.parent.right;
840
+ }
841
+ setNodeColor(w, getNodeColor(x.parent));
842
+ setNodeColor(x.parent, 0 /* NodeColor.Black */);
843
+ setNodeColor(w.right, 0 /* NodeColor.Black */);
844
+ leftRotate(T, x.parent);
845
+ x = T.root;
846
+ }
847
+ }
848
+ else {
849
+ w = x.parent.left;
850
+ if (getNodeColor(w) === 1 /* NodeColor.Red */) {
851
+ setNodeColor(w, 0 /* NodeColor.Black */);
852
+ setNodeColor(x.parent, 1 /* NodeColor.Red */);
853
+ rightRotate(T, x.parent);
854
+ w = x.parent.left;
855
+ }
856
+ if (getNodeColor(w.left) === 0 /* NodeColor.Black */ && getNodeColor(w.right) === 0 /* NodeColor.Black */) {
857
+ setNodeColor(w, 1 /* NodeColor.Red */);
858
+ x = x.parent;
859
+ }
860
+ else {
861
+ if (getNodeColor(w.left) === 0 /* NodeColor.Black */) {
862
+ setNodeColor(w.right, 0 /* NodeColor.Black */);
863
+ setNodeColor(w, 1 /* NodeColor.Red */);
864
+ leftRotate(T, w);
865
+ w = x.parent.left;
866
+ }
867
+ setNodeColor(w, getNodeColor(x.parent));
868
+ setNodeColor(x.parent, 0 /* NodeColor.Black */);
869
+ setNodeColor(w.left, 0 /* NodeColor.Black */);
870
+ rightRotate(T, x.parent);
871
+ x = T.root;
872
+ }
873
+ }
874
+ }
875
+ setNodeColor(x, 0 /* NodeColor.Black */);
876
+ resetSentinel();
877
+ }
878
+ function leftest(node) {
879
+ while (node.left !== SENTINEL) {
880
+ node = node.left;
881
+ }
882
+ return node;
883
+ }
884
+ function resetSentinel() {
885
+ SENTINEL.parent = SENTINEL;
886
+ SENTINEL.delta = 0; // optional
887
+ SENTINEL.start = 0; // optional
888
+ SENTINEL.end = 0; // optional
889
+ }
890
+ //#endregion
891
+ //#region Rotations
892
+ function leftRotate(T, x) {
893
+ const y = x.right; // set y.
894
+ y.delta += x.delta; // y's delta is no longer influenced by x's delta
895
+ if (y.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || y.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
896
+ T.requestNormalizeDelta = true;
897
+ }
898
+ y.start += x.delta;
899
+ y.end += x.delta;
900
+ x.right = y.left; // turn y's left subtree into x's right subtree.
901
+ if (y.left !== SENTINEL) {
902
+ y.left.parent = x;
903
+ }
904
+ y.parent = x.parent; // link x's parent to y.
905
+ if (x.parent === SENTINEL) {
906
+ T.root = y;
907
+ }
908
+ else if (x === x.parent.left) {
909
+ x.parent.left = y;
910
+ }
911
+ else {
912
+ x.parent.right = y;
913
+ }
914
+ y.left = x; // put x on y's left.
915
+ x.parent = y;
916
+ recomputeMaxEnd(x);
917
+ recomputeMaxEnd(y);
918
+ }
919
+ function rightRotate(T, y) {
920
+ const x = y.left;
921
+ y.delta -= x.delta;
922
+ if (y.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || y.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
923
+ T.requestNormalizeDelta = true;
924
+ }
925
+ y.start -= x.delta;
926
+ y.end -= x.delta;
927
+ y.left = x.right;
928
+ if (x.right !== SENTINEL) {
929
+ x.right.parent = y;
930
+ }
931
+ x.parent = y.parent;
932
+ if (y.parent === SENTINEL) {
933
+ T.root = x;
934
+ }
935
+ else if (y === y.parent.right) {
936
+ y.parent.right = x;
937
+ }
938
+ else {
939
+ y.parent.left = x;
940
+ }
941
+ x.right = y;
942
+ y.parent = x;
943
+ recomputeMaxEnd(y);
944
+ recomputeMaxEnd(x);
945
+ }
946
+ //#endregion
947
+ //#region max end computation
948
+ function computeMaxEnd(node) {
949
+ let maxEnd = node.end;
950
+ if (node.left !== SENTINEL) {
951
+ const leftMaxEnd = node.left.maxEnd;
952
+ if (leftMaxEnd > maxEnd) {
953
+ maxEnd = leftMaxEnd;
954
+ }
955
+ }
956
+ if (node.right !== SENTINEL) {
957
+ const rightMaxEnd = node.right.maxEnd + node.delta;
958
+ if (rightMaxEnd > maxEnd) {
959
+ maxEnd = rightMaxEnd;
960
+ }
961
+ }
962
+ return maxEnd;
963
+ }
964
+ export function recomputeMaxEnd(node) {
965
+ node.maxEnd = computeMaxEnd(node);
966
+ }
967
+ function recomputeMaxEndWalkToRoot(node) {
968
+ while (node !== SENTINEL) {
969
+ const maxEnd = computeMaxEnd(node);
970
+ if (node.maxEnd === maxEnd) {
971
+ // no need to go further
972
+ return;
973
+ }
974
+ node.maxEnd = maxEnd;
975
+ node = node.parent;
976
+ }
977
+ }
978
+ //#endregion
979
+ //#region utils
980
+ export function intervalCompare(aStart, aEnd, bStart, bEnd) {
981
+ if (aStart === bStart) {
982
+ return aEnd - bEnd;
983
+ }
984
+ return aStart - bStart;
985
+ }
986
+ //#endregion
node_modules/monaco-editor/esm/vs/editor/common/model/mirrorTextModel.js ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { splitLines } from '../../../base/common/strings.js';
6
+ import { Position } from '../core/position.js';
7
+ import { PrefixSumComputer } from './prefixSumComputer.js';
8
+ export class MirrorTextModel {
9
+ constructor(uri, lines, eol, versionId) {
10
+ this._uri = uri;
11
+ this._lines = lines;
12
+ this._eol = eol;
13
+ this._versionId = versionId;
14
+ this._lineStarts = null;
15
+ this._cachedTextValue = null;
16
+ }
17
+ dispose() {
18
+ this._lines.length = 0;
19
+ }
20
+ get version() {
21
+ return this._versionId;
22
+ }
23
+ getText() {
24
+ if (this._cachedTextValue === null) {
25
+ this._cachedTextValue = this._lines.join(this._eol);
26
+ }
27
+ return this._cachedTextValue;
28
+ }
29
+ onEvents(e) {
30
+ if (e.eol && e.eol !== this._eol) {
31
+ this._eol = e.eol;
32
+ this._lineStarts = null;
33
+ }
34
+ // Update my lines
35
+ const changes = e.changes;
36
+ for (const change of changes) {
37
+ this._acceptDeleteRange(change.range);
38
+ this._acceptInsertText(new Position(change.range.startLineNumber, change.range.startColumn), change.text);
39
+ }
40
+ this._versionId = e.versionId;
41
+ this._cachedTextValue = null;
42
+ }
43
+ _ensureLineStarts() {
44
+ if (!this._lineStarts) {
45
+ const eolLength = this._eol.length;
46
+ const linesLength = this._lines.length;
47
+ const lineStartValues = new Uint32Array(linesLength);
48
+ for (let i = 0; i < linesLength; i++) {
49
+ lineStartValues[i] = this._lines[i].length + eolLength;
50
+ }
51
+ this._lineStarts = new PrefixSumComputer(lineStartValues);
52
+ }
53
+ }
54
+ /**
55
+ * All changes to a line's text go through this method
56
+ */
57
+ _setLineText(lineIndex, newValue) {
58
+ this._lines[lineIndex] = newValue;
59
+ if (this._lineStarts) {
60
+ // update prefix sum
61
+ this._lineStarts.setValue(lineIndex, this._lines[lineIndex].length + this._eol.length);
62
+ }
63
+ }
64
+ _acceptDeleteRange(range) {
65
+ if (range.startLineNumber === range.endLineNumber) {
66
+ if (range.startColumn === range.endColumn) {
67
+ // Nothing to delete
68
+ return;
69
+ }
70
+ // Delete text on the affected line
71
+ this._setLineText(range.startLineNumber - 1, this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1)
72
+ + this._lines[range.startLineNumber - 1].substring(range.endColumn - 1));
73
+ return;
74
+ }
75
+ // Take remaining text on last line and append it to remaining text on first line
76
+ this._setLineText(range.startLineNumber - 1, this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1)
77
+ + this._lines[range.endLineNumber - 1].substring(range.endColumn - 1));
78
+ // Delete middle lines
79
+ this._lines.splice(range.startLineNumber, range.endLineNumber - range.startLineNumber);
80
+ if (this._lineStarts) {
81
+ // update prefix sum
82
+ this._lineStarts.removeValues(range.startLineNumber, range.endLineNumber - range.startLineNumber);
83
+ }
84
+ }
85
+ _acceptInsertText(position, insertText) {
86
+ if (insertText.length === 0) {
87
+ // Nothing to insert
88
+ return;
89
+ }
90
+ const insertLines = splitLines(insertText);
91
+ if (insertLines.length === 1) {
92
+ // Inserting text on one line
93
+ this._setLineText(position.lineNumber - 1, this._lines[position.lineNumber - 1].substring(0, position.column - 1)
94
+ + insertLines[0]
95
+ + this._lines[position.lineNumber - 1].substring(position.column - 1));
96
+ return;
97
+ }
98
+ // Append overflowing text from first line to the end of text to insert
99
+ insertLines[insertLines.length - 1] += this._lines[position.lineNumber - 1].substring(position.column - 1);
100
+ // Delete overflowing text from first line and insert text on first line
101
+ this._setLineText(position.lineNumber - 1, this._lines[position.lineNumber - 1].substring(0, position.column - 1)
102
+ + insertLines[0]);
103
+ // Insert new lines & store lengths
104
+ const newLengths = new Uint32Array(insertLines.length - 1);
105
+ for (let i = 1; i < insertLines.length; i++) {
106
+ this._lines.splice(position.lineNumber + i - 1, 0, insertLines[i]);
107
+ newLengths[i - 1] = insertLines[i].length + this._eol.length;
108
+ }
109
+ if (this._lineStarts) {
110
+ // update prefix sum
111
+ this._lineStarts.insertValues(position.lineNumber, newLengths);
112
+ }
113
+ }
114
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.js ADDED
@@ -0,0 +1,1452 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { Position } from '../../core/position.js';
6
+ import { Range } from '../../core/range.js';
7
+ import { FindMatch } from '../../model.js';
8
+ import { SENTINEL, TreeNode, fixInsert, leftest, rbDelete, righttest, updateTreeMetadata } from './rbTreeBase.js';
9
+ import { Searcher, createFindMatch, isValidMatch } from '../textModelSearch.js';
10
+ // const lfRegex = new RegExp(/\r\n|\r|\n/g);
11
+ const AverageBufferSize = 65535;
12
+ function createUintArray(arr) {
13
+ let r;
14
+ if (arr[arr.length - 1] < 65536) {
15
+ r = new Uint16Array(arr.length);
16
+ }
17
+ else {
18
+ r = new Uint32Array(arr.length);
19
+ }
20
+ r.set(arr, 0);
21
+ return r;
22
+ }
23
+ class LineStarts {
24
+ constructor(lineStarts, cr, lf, crlf, isBasicASCII) {
25
+ this.lineStarts = lineStarts;
26
+ this.cr = cr;
27
+ this.lf = lf;
28
+ this.crlf = crlf;
29
+ this.isBasicASCII = isBasicASCII;
30
+ }
31
+ }
32
+ export function createLineStartsFast(str, readonly = true) {
33
+ const r = [0];
34
+ let rLength = 1;
35
+ for (let i = 0, len = str.length; i < len; i++) {
36
+ const chr = str.charCodeAt(i);
37
+ if (chr === 13 /* CharCode.CarriageReturn */) {
38
+ if (i + 1 < len && str.charCodeAt(i + 1) === 10 /* CharCode.LineFeed */) {
39
+ // \r\n... case
40
+ r[rLength++] = i + 2;
41
+ i++; // skip \n
42
+ }
43
+ else {
44
+ // \r... case
45
+ r[rLength++] = i + 1;
46
+ }
47
+ }
48
+ else if (chr === 10 /* CharCode.LineFeed */) {
49
+ r[rLength++] = i + 1;
50
+ }
51
+ }
52
+ if (readonly) {
53
+ return createUintArray(r);
54
+ }
55
+ else {
56
+ return r;
57
+ }
58
+ }
59
+ export function createLineStarts(r, str) {
60
+ r.length = 0;
61
+ r[0] = 0;
62
+ let rLength = 1;
63
+ let cr = 0, lf = 0, crlf = 0;
64
+ let isBasicASCII = true;
65
+ for (let i = 0, len = str.length; i < len; i++) {
66
+ const chr = str.charCodeAt(i);
67
+ if (chr === 13 /* CharCode.CarriageReturn */) {
68
+ if (i + 1 < len && str.charCodeAt(i + 1) === 10 /* CharCode.LineFeed */) {
69
+ // \r\n... case
70
+ crlf++;
71
+ r[rLength++] = i + 2;
72
+ i++; // skip \n
73
+ }
74
+ else {
75
+ cr++;
76
+ // \r... case
77
+ r[rLength++] = i + 1;
78
+ }
79
+ }
80
+ else if (chr === 10 /* CharCode.LineFeed */) {
81
+ lf++;
82
+ r[rLength++] = i + 1;
83
+ }
84
+ else {
85
+ if (isBasicASCII) {
86
+ if (chr !== 9 /* CharCode.Tab */ && (chr < 32 || chr > 126)) {
87
+ isBasicASCII = false;
88
+ }
89
+ }
90
+ }
91
+ }
92
+ const result = new LineStarts(createUintArray(r), cr, lf, crlf, isBasicASCII);
93
+ r.length = 0;
94
+ return result;
95
+ }
96
+ export class Piece {
97
+ constructor(bufferIndex, start, end, lineFeedCnt, length) {
98
+ this.bufferIndex = bufferIndex;
99
+ this.start = start;
100
+ this.end = end;
101
+ this.lineFeedCnt = lineFeedCnt;
102
+ this.length = length;
103
+ }
104
+ }
105
+ export class StringBuffer {
106
+ constructor(buffer, lineStarts) {
107
+ this.buffer = buffer;
108
+ this.lineStarts = lineStarts;
109
+ }
110
+ }
111
+ /**
112
+ * Readonly snapshot for piece tree.
113
+ * In a real multiple thread environment, to make snapshot reading always work correctly, we need to
114
+ * 1. Make TreeNode.piece immutable, then reading and writing can run in parallel.
115
+ * 2. TreeNode/Buffers normalization should not happen during snapshot reading.
116
+ */
117
+ class PieceTreeSnapshot {
118
+ constructor(tree, BOM) {
119
+ this._pieces = [];
120
+ this._tree = tree;
121
+ this._BOM = BOM;
122
+ this._index = 0;
123
+ if (tree.root !== SENTINEL) {
124
+ tree.iterate(tree.root, node => {
125
+ if (node !== SENTINEL) {
126
+ this._pieces.push(node.piece);
127
+ }
128
+ return true;
129
+ });
130
+ }
131
+ }
132
+ read() {
133
+ if (this._pieces.length === 0) {
134
+ if (this._index === 0) {
135
+ this._index++;
136
+ return this._BOM;
137
+ }
138
+ else {
139
+ return null;
140
+ }
141
+ }
142
+ if (this._index > this._pieces.length - 1) {
143
+ return null;
144
+ }
145
+ if (this._index === 0) {
146
+ return this._BOM + this._tree.getPieceContent(this._pieces[this._index++]);
147
+ }
148
+ return this._tree.getPieceContent(this._pieces[this._index++]);
149
+ }
150
+ }
151
+ class PieceTreeSearchCache {
152
+ constructor(limit) {
153
+ this._limit = limit;
154
+ this._cache = [];
155
+ }
156
+ get(offset) {
157
+ for (let i = this._cache.length - 1; i >= 0; i--) {
158
+ const nodePos = this._cache[i];
159
+ if (nodePos.nodeStartOffset <= offset && nodePos.nodeStartOffset + nodePos.node.piece.length >= offset) {
160
+ return nodePos;
161
+ }
162
+ }
163
+ return null;
164
+ }
165
+ get2(lineNumber) {
166
+ for (let i = this._cache.length - 1; i >= 0; i--) {
167
+ const nodePos = this._cache[i];
168
+ if (nodePos.nodeStartLineNumber && nodePos.nodeStartLineNumber < lineNumber && nodePos.nodeStartLineNumber + nodePos.node.piece.lineFeedCnt >= lineNumber) {
169
+ return nodePos;
170
+ }
171
+ }
172
+ return null;
173
+ }
174
+ set(nodePosition) {
175
+ if (this._cache.length >= this._limit) {
176
+ this._cache.shift();
177
+ }
178
+ this._cache.push(nodePosition);
179
+ }
180
+ validate(offset) {
181
+ let hasInvalidVal = false;
182
+ const tmp = this._cache;
183
+ for (let i = 0; i < tmp.length; i++) {
184
+ const nodePos = tmp[i];
185
+ if (nodePos.node.parent === null || nodePos.nodeStartOffset >= offset) {
186
+ tmp[i] = null;
187
+ hasInvalidVal = true;
188
+ continue;
189
+ }
190
+ }
191
+ if (hasInvalidVal) {
192
+ const newArr = [];
193
+ for (const entry of tmp) {
194
+ if (entry !== null) {
195
+ newArr.push(entry);
196
+ }
197
+ }
198
+ this._cache = newArr;
199
+ }
200
+ }
201
+ }
202
+ export class PieceTreeBase {
203
+ constructor(chunks, eol, eolNormalized) {
204
+ this.create(chunks, eol, eolNormalized);
205
+ }
206
+ create(chunks, eol, eolNormalized) {
207
+ this._buffers = [
208
+ new StringBuffer('', [0])
209
+ ];
210
+ this._lastChangeBufferPos = { line: 0, column: 0 };
211
+ this.root = SENTINEL;
212
+ this._lineCnt = 1;
213
+ this._length = 0;
214
+ this._EOL = eol;
215
+ this._EOLLength = eol.length;
216
+ this._EOLNormalized = eolNormalized;
217
+ let lastNode = null;
218
+ for (let i = 0, len = chunks.length; i < len; i++) {
219
+ if (chunks[i].buffer.length > 0) {
220
+ if (!chunks[i].lineStarts) {
221
+ chunks[i].lineStarts = createLineStartsFast(chunks[i].buffer);
222
+ }
223
+ const piece = new Piece(i + 1, { line: 0, column: 0 }, { line: chunks[i].lineStarts.length - 1, column: chunks[i].buffer.length - chunks[i].lineStarts[chunks[i].lineStarts.length - 1] }, chunks[i].lineStarts.length - 1, chunks[i].buffer.length);
224
+ this._buffers.push(chunks[i]);
225
+ lastNode = this.rbInsertRight(lastNode, piece);
226
+ }
227
+ }
228
+ this._searchCache = new PieceTreeSearchCache(1);
229
+ this._lastVisitedLine = { lineNumber: 0, value: '' };
230
+ this.computeBufferMetadata();
231
+ }
232
+ normalizeEOL(eol) {
233
+ const averageBufferSize = AverageBufferSize;
234
+ const min = averageBufferSize - Math.floor(averageBufferSize / 3);
235
+ const max = min * 2;
236
+ let tempChunk = '';
237
+ let tempChunkLen = 0;
238
+ const chunks = [];
239
+ this.iterate(this.root, node => {
240
+ const str = this.getNodeContent(node);
241
+ const len = str.length;
242
+ if (tempChunkLen <= min || tempChunkLen + len < max) {
243
+ tempChunk += str;
244
+ tempChunkLen += len;
245
+ return true;
246
+ }
247
+ // flush anyways
248
+ const text = tempChunk.replace(/\r\n|\r|\n/g, eol);
249
+ chunks.push(new StringBuffer(text, createLineStartsFast(text)));
250
+ tempChunk = str;
251
+ tempChunkLen = len;
252
+ return true;
253
+ });
254
+ if (tempChunkLen > 0) {
255
+ const text = tempChunk.replace(/\r\n|\r|\n/g, eol);
256
+ chunks.push(new StringBuffer(text, createLineStartsFast(text)));
257
+ }
258
+ this.create(chunks, eol, true);
259
+ }
260
+ // #region Buffer API
261
+ getEOL() {
262
+ return this._EOL;
263
+ }
264
+ setEOL(newEOL) {
265
+ this._EOL = newEOL;
266
+ this._EOLLength = this._EOL.length;
267
+ this.normalizeEOL(newEOL);
268
+ }
269
+ createSnapshot(BOM) {
270
+ return new PieceTreeSnapshot(this, BOM);
271
+ }
272
+ getOffsetAt(lineNumber, column) {
273
+ let leftLen = 0; // inorder
274
+ let x = this.root;
275
+ while (x !== SENTINEL) {
276
+ if (x.left !== SENTINEL && x.lf_left + 1 >= lineNumber) {
277
+ x = x.left;
278
+ }
279
+ else if (x.lf_left + x.piece.lineFeedCnt + 1 >= lineNumber) {
280
+ leftLen += x.size_left;
281
+ // lineNumber >= 2
282
+ const accumualtedValInCurrentIndex = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2);
283
+ return leftLen += accumualtedValInCurrentIndex + column - 1;
284
+ }
285
+ else {
286
+ lineNumber -= x.lf_left + x.piece.lineFeedCnt;
287
+ leftLen += x.size_left + x.piece.length;
288
+ x = x.right;
289
+ }
290
+ }
291
+ return leftLen;
292
+ }
293
+ getPositionAt(offset) {
294
+ offset = Math.floor(offset);
295
+ offset = Math.max(0, offset);
296
+ let x = this.root;
297
+ let lfCnt = 0;
298
+ const originalOffset = offset;
299
+ while (x !== SENTINEL) {
300
+ if (x.size_left !== 0 && x.size_left >= offset) {
301
+ x = x.left;
302
+ }
303
+ else if (x.size_left + x.piece.length >= offset) {
304
+ const out = this.getIndexOf(x, offset - x.size_left);
305
+ lfCnt += x.lf_left + out.index;
306
+ if (out.index === 0) {
307
+ const lineStartOffset = this.getOffsetAt(lfCnt + 1, 1);
308
+ const column = originalOffset - lineStartOffset;
309
+ return new Position(lfCnt + 1, column + 1);
310
+ }
311
+ return new Position(lfCnt + 1, out.remainder + 1);
312
+ }
313
+ else {
314
+ offset -= x.size_left + x.piece.length;
315
+ lfCnt += x.lf_left + x.piece.lineFeedCnt;
316
+ if (x.right === SENTINEL) {
317
+ // last node
318
+ const lineStartOffset = this.getOffsetAt(lfCnt + 1, 1);
319
+ const column = originalOffset - offset - lineStartOffset;
320
+ return new Position(lfCnt + 1, column + 1);
321
+ }
322
+ else {
323
+ x = x.right;
324
+ }
325
+ }
326
+ }
327
+ return new Position(1, 1);
328
+ }
329
+ getValueInRange(range, eol) {
330
+ if (range.startLineNumber === range.endLineNumber && range.startColumn === range.endColumn) {
331
+ return '';
332
+ }
333
+ const startPosition = this.nodeAt2(range.startLineNumber, range.startColumn);
334
+ const endPosition = this.nodeAt2(range.endLineNumber, range.endColumn);
335
+ const value = this.getValueInRange2(startPosition, endPosition);
336
+ if (eol) {
337
+ if (eol !== this._EOL || !this._EOLNormalized) {
338
+ return value.replace(/\r\n|\r|\n/g, eol);
339
+ }
340
+ if (eol === this.getEOL() && this._EOLNormalized) {
341
+ if (eol === '\r\n') {
342
+ }
343
+ return value;
344
+ }
345
+ return value.replace(/\r\n|\r|\n/g, eol);
346
+ }
347
+ return value;
348
+ }
349
+ getValueInRange2(startPosition, endPosition) {
350
+ if (startPosition.node === endPosition.node) {
351
+ const node = startPosition.node;
352
+ const buffer = this._buffers[node.piece.bufferIndex].buffer;
353
+ const startOffset = this.offsetInBuffer(node.piece.bufferIndex, node.piece.start);
354
+ return buffer.substring(startOffset + startPosition.remainder, startOffset + endPosition.remainder);
355
+ }
356
+ let x = startPosition.node;
357
+ const buffer = this._buffers[x.piece.bufferIndex].buffer;
358
+ const startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start);
359
+ let ret = buffer.substring(startOffset + startPosition.remainder, startOffset + x.piece.length);
360
+ x = x.next();
361
+ while (x !== SENTINEL) {
362
+ const buffer = this._buffers[x.piece.bufferIndex].buffer;
363
+ const startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start);
364
+ if (x === endPosition.node) {
365
+ ret += buffer.substring(startOffset, startOffset + endPosition.remainder);
366
+ break;
367
+ }
368
+ else {
369
+ ret += buffer.substr(startOffset, x.piece.length);
370
+ }
371
+ x = x.next();
372
+ }
373
+ return ret;
374
+ }
375
+ getLinesContent() {
376
+ const lines = [];
377
+ let linesLength = 0;
378
+ let currentLine = '';
379
+ let danglingCR = false;
380
+ this.iterate(this.root, node => {
381
+ if (node === SENTINEL) {
382
+ return true;
383
+ }
384
+ const piece = node.piece;
385
+ let pieceLength = piece.length;
386
+ if (pieceLength === 0) {
387
+ return true;
388
+ }
389
+ const buffer = this._buffers[piece.bufferIndex].buffer;
390
+ const lineStarts = this._buffers[piece.bufferIndex].lineStarts;
391
+ const pieceStartLine = piece.start.line;
392
+ const pieceEndLine = piece.end.line;
393
+ let pieceStartOffset = lineStarts[pieceStartLine] + piece.start.column;
394
+ if (danglingCR) {
395
+ if (buffer.charCodeAt(pieceStartOffset) === 10 /* CharCode.LineFeed */) {
396
+ // pretend the \n was in the previous piece..
397
+ pieceStartOffset++;
398
+ pieceLength--;
399
+ }
400
+ lines[linesLength++] = currentLine;
401
+ currentLine = '';
402
+ danglingCR = false;
403
+ if (pieceLength === 0) {
404
+ return true;
405
+ }
406
+ }
407
+ if (pieceStartLine === pieceEndLine) {
408
+ // this piece has no new lines
409
+ if (!this._EOLNormalized && buffer.charCodeAt(pieceStartOffset + pieceLength - 1) === 13 /* CharCode.CarriageReturn */) {
410
+ danglingCR = true;
411
+ currentLine += buffer.substr(pieceStartOffset, pieceLength - 1);
412
+ }
413
+ else {
414
+ currentLine += buffer.substr(pieceStartOffset, pieceLength);
415
+ }
416
+ return true;
417
+ }
418
+ // add the text before the first line start in this piece
419
+ currentLine += (this._EOLNormalized
420
+ ? buffer.substring(pieceStartOffset, Math.max(pieceStartOffset, lineStarts[pieceStartLine + 1] - this._EOLLength))
421
+ : buffer.substring(pieceStartOffset, lineStarts[pieceStartLine + 1]).replace(/(\r\n|\r|\n)$/, ''));
422
+ lines[linesLength++] = currentLine;
423
+ for (let line = pieceStartLine + 1; line < pieceEndLine; line++) {
424
+ currentLine = (this._EOLNormalized
425
+ ? buffer.substring(lineStarts[line], lineStarts[line + 1] - this._EOLLength)
426
+ : buffer.substring(lineStarts[line], lineStarts[line + 1]).replace(/(\r\n|\r|\n)$/, ''));
427
+ lines[linesLength++] = currentLine;
428
+ }
429
+ if (!this._EOLNormalized && buffer.charCodeAt(lineStarts[pieceEndLine] + piece.end.column - 1) === 13 /* CharCode.CarriageReturn */) {
430
+ danglingCR = true;
431
+ if (piece.end.column === 0) {
432
+ // The last line ended with a \r, let's undo the push, it will be pushed by next iteration
433
+ linesLength--;
434
+ }
435
+ else {
436
+ currentLine = buffer.substr(lineStarts[pieceEndLine], piece.end.column - 1);
437
+ }
438
+ }
439
+ else {
440
+ currentLine = buffer.substr(lineStarts[pieceEndLine], piece.end.column);
441
+ }
442
+ return true;
443
+ });
444
+ if (danglingCR) {
445
+ lines[linesLength++] = currentLine;
446
+ currentLine = '';
447
+ }
448
+ lines[linesLength++] = currentLine;
449
+ return lines;
450
+ }
451
+ getLength() {
452
+ return this._length;
453
+ }
454
+ getLineCount() {
455
+ return this._lineCnt;
456
+ }
457
+ getLineContent(lineNumber) {
458
+ if (this._lastVisitedLine.lineNumber === lineNumber) {
459
+ return this._lastVisitedLine.value;
460
+ }
461
+ this._lastVisitedLine.lineNumber = lineNumber;
462
+ if (lineNumber === this._lineCnt) {
463
+ this._lastVisitedLine.value = this.getLineRawContent(lineNumber);
464
+ }
465
+ else if (this._EOLNormalized) {
466
+ this._lastVisitedLine.value = this.getLineRawContent(lineNumber, this._EOLLength);
467
+ }
468
+ else {
469
+ this._lastVisitedLine.value = this.getLineRawContent(lineNumber).replace(/(\r\n|\r|\n)$/, '');
470
+ }
471
+ return this._lastVisitedLine.value;
472
+ }
473
+ _getCharCode(nodePos) {
474
+ if (nodePos.remainder === nodePos.node.piece.length) {
475
+ // the char we want to fetch is at the head of next node.
476
+ const matchingNode = nodePos.node.next();
477
+ if (!matchingNode) {
478
+ return 0;
479
+ }
480
+ const buffer = this._buffers[matchingNode.piece.bufferIndex];
481
+ const startOffset = this.offsetInBuffer(matchingNode.piece.bufferIndex, matchingNode.piece.start);
482
+ return buffer.buffer.charCodeAt(startOffset);
483
+ }
484
+ else {
485
+ const buffer = this._buffers[nodePos.node.piece.bufferIndex];
486
+ const startOffset = this.offsetInBuffer(nodePos.node.piece.bufferIndex, nodePos.node.piece.start);
487
+ const targetOffset = startOffset + nodePos.remainder;
488
+ return buffer.buffer.charCodeAt(targetOffset);
489
+ }
490
+ }
491
+ getLineCharCode(lineNumber, index) {
492
+ const nodePos = this.nodeAt2(lineNumber, index + 1);
493
+ return this._getCharCode(nodePos);
494
+ }
495
+ getLineLength(lineNumber) {
496
+ if (lineNumber === this.getLineCount()) {
497
+ const startOffset = this.getOffsetAt(lineNumber, 1);
498
+ return this.getLength() - startOffset;
499
+ }
500
+ return this.getOffsetAt(lineNumber + 1, 1) - this.getOffsetAt(lineNumber, 1) - this._EOLLength;
501
+ }
502
+ findMatchesInNode(node, searcher, startLineNumber, startColumn, startCursor, endCursor, searchData, captureMatches, limitResultCount, resultLen, result) {
503
+ const buffer = this._buffers[node.piece.bufferIndex];
504
+ const startOffsetInBuffer = this.offsetInBuffer(node.piece.bufferIndex, node.piece.start);
505
+ const start = this.offsetInBuffer(node.piece.bufferIndex, startCursor);
506
+ const end = this.offsetInBuffer(node.piece.bufferIndex, endCursor);
507
+ let m;
508
+ // Reset regex to search from the beginning
509
+ const ret = { line: 0, column: 0 };
510
+ let searchText;
511
+ let offsetInBuffer;
512
+ if (searcher._wordSeparators) {
513
+ searchText = buffer.buffer.substring(start, end);
514
+ offsetInBuffer = (offset) => offset + start;
515
+ searcher.reset(0);
516
+ }
517
+ else {
518
+ searchText = buffer.buffer;
519
+ offsetInBuffer = (offset) => offset;
520
+ searcher.reset(start);
521
+ }
522
+ do {
523
+ m = searcher.next(searchText);
524
+ if (m) {
525
+ if (offsetInBuffer(m.index) >= end) {
526
+ return resultLen;
527
+ }
528
+ this.positionInBuffer(node, offsetInBuffer(m.index) - startOffsetInBuffer, ret);
529
+ const lineFeedCnt = this.getLineFeedCnt(node.piece.bufferIndex, startCursor, ret);
530
+ const retStartColumn = ret.line === startCursor.line ? ret.column - startCursor.column + startColumn : ret.column + 1;
531
+ const retEndColumn = retStartColumn + m[0].length;
532
+ result[resultLen++] = createFindMatch(new Range(startLineNumber + lineFeedCnt, retStartColumn, startLineNumber + lineFeedCnt, retEndColumn), m, captureMatches);
533
+ if (offsetInBuffer(m.index) + m[0].length >= end) {
534
+ return resultLen;
535
+ }
536
+ if (resultLen >= limitResultCount) {
537
+ return resultLen;
538
+ }
539
+ }
540
+ } while (m);
541
+ return resultLen;
542
+ }
543
+ findMatchesLineByLine(searchRange, searchData, captureMatches, limitResultCount) {
544
+ const result = [];
545
+ let resultLen = 0;
546
+ const searcher = new Searcher(searchData.wordSeparators, searchData.regex);
547
+ let startPosition = this.nodeAt2(searchRange.startLineNumber, searchRange.startColumn);
548
+ if (startPosition === null) {
549
+ return [];
550
+ }
551
+ const endPosition = this.nodeAt2(searchRange.endLineNumber, searchRange.endColumn);
552
+ if (endPosition === null) {
553
+ return [];
554
+ }
555
+ let start = this.positionInBuffer(startPosition.node, startPosition.remainder);
556
+ const end = this.positionInBuffer(endPosition.node, endPosition.remainder);
557
+ if (startPosition.node === endPosition.node) {
558
+ this.findMatchesInNode(startPosition.node, searcher, searchRange.startLineNumber, searchRange.startColumn, start, end, searchData, captureMatches, limitResultCount, resultLen, result);
559
+ return result;
560
+ }
561
+ let startLineNumber = searchRange.startLineNumber;
562
+ let currentNode = startPosition.node;
563
+ while (currentNode !== endPosition.node) {
564
+ const lineBreakCnt = this.getLineFeedCnt(currentNode.piece.bufferIndex, start, currentNode.piece.end);
565
+ if (lineBreakCnt >= 1) {
566
+ // last line break position
567
+ const lineStarts = this._buffers[currentNode.piece.bufferIndex].lineStarts;
568
+ const startOffsetInBuffer = this.offsetInBuffer(currentNode.piece.bufferIndex, currentNode.piece.start);
569
+ const nextLineStartOffset = lineStarts[start.line + lineBreakCnt];
570
+ const startColumn = startLineNumber === searchRange.startLineNumber ? searchRange.startColumn : 1;
571
+ resultLen = this.findMatchesInNode(currentNode, searcher, startLineNumber, startColumn, start, this.positionInBuffer(currentNode, nextLineStartOffset - startOffsetInBuffer), searchData, captureMatches, limitResultCount, resultLen, result);
572
+ if (resultLen >= limitResultCount) {
573
+ return result;
574
+ }
575
+ startLineNumber += lineBreakCnt;
576
+ }
577
+ const startColumn = startLineNumber === searchRange.startLineNumber ? searchRange.startColumn - 1 : 0;
578
+ // search for the remaining content
579
+ if (startLineNumber === searchRange.endLineNumber) {
580
+ const text = this.getLineContent(startLineNumber).substring(startColumn, searchRange.endColumn - 1);
581
+ resultLen = this._findMatchesInLine(searchData, searcher, text, searchRange.endLineNumber, startColumn, resultLen, result, captureMatches, limitResultCount);
582
+ return result;
583
+ }
584
+ resultLen = this._findMatchesInLine(searchData, searcher, this.getLineContent(startLineNumber).substr(startColumn), startLineNumber, startColumn, resultLen, result, captureMatches, limitResultCount);
585
+ if (resultLen >= limitResultCount) {
586
+ return result;
587
+ }
588
+ startLineNumber++;
589
+ startPosition = this.nodeAt2(startLineNumber, 1);
590
+ currentNode = startPosition.node;
591
+ start = this.positionInBuffer(startPosition.node, startPosition.remainder);
592
+ }
593
+ if (startLineNumber === searchRange.endLineNumber) {
594
+ const startColumn = startLineNumber === searchRange.startLineNumber ? searchRange.startColumn - 1 : 0;
595
+ const text = this.getLineContent(startLineNumber).substring(startColumn, searchRange.endColumn - 1);
596
+ resultLen = this._findMatchesInLine(searchData, searcher, text, searchRange.endLineNumber, startColumn, resultLen, result, captureMatches, limitResultCount);
597
+ return result;
598
+ }
599
+ const startColumn = startLineNumber === searchRange.startLineNumber ? searchRange.startColumn : 1;
600
+ resultLen = this.findMatchesInNode(endPosition.node, searcher, startLineNumber, startColumn, start, end, searchData, captureMatches, limitResultCount, resultLen, result);
601
+ return result;
602
+ }
603
+ _findMatchesInLine(searchData, searcher, text, lineNumber, deltaOffset, resultLen, result, captureMatches, limitResultCount) {
604
+ const wordSeparators = searchData.wordSeparators;
605
+ if (!captureMatches && searchData.simpleSearch) {
606
+ const searchString = searchData.simpleSearch;
607
+ const searchStringLen = searchString.length;
608
+ const textLength = text.length;
609
+ let lastMatchIndex = -searchStringLen;
610
+ while ((lastMatchIndex = text.indexOf(searchString, lastMatchIndex + searchStringLen)) !== -1) {
611
+ if (!wordSeparators || isValidMatch(wordSeparators, text, textLength, lastMatchIndex, searchStringLen)) {
612
+ result[resultLen++] = new FindMatch(new Range(lineNumber, lastMatchIndex + 1 + deltaOffset, lineNumber, lastMatchIndex + 1 + searchStringLen + deltaOffset), null);
613
+ if (resultLen >= limitResultCount) {
614
+ return resultLen;
615
+ }
616
+ }
617
+ }
618
+ return resultLen;
619
+ }
620
+ let m;
621
+ // Reset regex to search from the beginning
622
+ searcher.reset(0);
623
+ do {
624
+ m = searcher.next(text);
625
+ if (m) {
626
+ result[resultLen++] = createFindMatch(new Range(lineNumber, m.index + 1 + deltaOffset, lineNumber, m.index + 1 + m[0].length + deltaOffset), m, captureMatches);
627
+ if (resultLen >= limitResultCount) {
628
+ return resultLen;
629
+ }
630
+ }
631
+ } while (m);
632
+ return resultLen;
633
+ }
634
+ // #endregion
635
+ // #region Piece Table
636
+ insert(offset, value, eolNormalized = false) {
637
+ this._EOLNormalized = this._EOLNormalized && eolNormalized;
638
+ this._lastVisitedLine.lineNumber = 0;
639
+ this._lastVisitedLine.value = '';
640
+ if (this.root !== SENTINEL) {
641
+ const { node, remainder, nodeStartOffset } = this.nodeAt(offset);
642
+ const piece = node.piece;
643
+ const bufferIndex = piece.bufferIndex;
644
+ const insertPosInBuffer = this.positionInBuffer(node, remainder);
645
+ if (node.piece.bufferIndex === 0 &&
646
+ piece.end.line === this._lastChangeBufferPos.line &&
647
+ piece.end.column === this._lastChangeBufferPos.column &&
648
+ (nodeStartOffset + piece.length === offset) &&
649
+ value.length < AverageBufferSize) {
650
+ // changed buffer
651
+ this.appendToNode(node, value);
652
+ this.computeBufferMetadata();
653
+ return;
654
+ }
655
+ if (nodeStartOffset === offset) {
656
+ this.insertContentToNodeLeft(value, node);
657
+ this._searchCache.validate(offset);
658
+ }
659
+ else if (nodeStartOffset + node.piece.length > offset) {
660
+ // we are inserting into the middle of a node.
661
+ const nodesToDel = [];
662
+ let newRightPiece = new Piece(piece.bufferIndex, insertPosInBuffer, piece.end, this.getLineFeedCnt(piece.bufferIndex, insertPosInBuffer, piece.end), this.offsetInBuffer(bufferIndex, piece.end) - this.offsetInBuffer(bufferIndex, insertPosInBuffer));
663
+ if (this.shouldCheckCRLF() && this.endWithCR(value)) {
664
+ const headOfRight = this.nodeCharCodeAt(node, remainder);
665
+ if (headOfRight === 10 /** \n */) {
666
+ const newStart = { line: newRightPiece.start.line + 1, column: 0 };
667
+ newRightPiece = new Piece(newRightPiece.bufferIndex, newStart, newRightPiece.end, this.getLineFeedCnt(newRightPiece.bufferIndex, newStart, newRightPiece.end), newRightPiece.length - 1);
668
+ value += '\n';
669
+ }
670
+ }
671
+ // reuse node for content before insertion point.
672
+ if (this.shouldCheckCRLF() && this.startWithLF(value)) {
673
+ const tailOfLeft = this.nodeCharCodeAt(node, remainder - 1);
674
+ if (tailOfLeft === 13 /** \r */) {
675
+ const previousPos = this.positionInBuffer(node, remainder - 1);
676
+ this.deleteNodeTail(node, previousPos);
677
+ value = '\r' + value;
678
+ if (node.piece.length === 0) {
679
+ nodesToDel.push(node);
680
+ }
681
+ }
682
+ else {
683
+ this.deleteNodeTail(node, insertPosInBuffer);
684
+ }
685
+ }
686
+ else {
687
+ this.deleteNodeTail(node, insertPosInBuffer);
688
+ }
689
+ const newPieces = this.createNewPieces(value);
690
+ if (newRightPiece.length > 0) {
691
+ this.rbInsertRight(node, newRightPiece);
692
+ }
693
+ let tmpNode = node;
694
+ for (let k = 0; k < newPieces.length; k++) {
695
+ tmpNode = this.rbInsertRight(tmpNode, newPieces[k]);
696
+ }
697
+ this.deleteNodes(nodesToDel);
698
+ }
699
+ else {
700
+ this.insertContentToNodeRight(value, node);
701
+ }
702
+ }
703
+ else {
704
+ // insert new node
705
+ const pieces = this.createNewPieces(value);
706
+ let node = this.rbInsertLeft(null, pieces[0]);
707
+ for (let k = 1; k < pieces.length; k++) {
708
+ node = this.rbInsertRight(node, pieces[k]);
709
+ }
710
+ }
711
+ // todo, this is too brutal. Total line feed count should be updated the same way as lf_left.
712
+ this.computeBufferMetadata();
713
+ }
714
+ delete(offset, cnt) {
715
+ this._lastVisitedLine.lineNumber = 0;
716
+ this._lastVisitedLine.value = '';
717
+ if (cnt <= 0 || this.root === SENTINEL) {
718
+ return;
719
+ }
720
+ const startPosition = this.nodeAt(offset);
721
+ const endPosition = this.nodeAt(offset + cnt);
722
+ const startNode = startPosition.node;
723
+ const endNode = endPosition.node;
724
+ if (startNode === endNode) {
725
+ const startSplitPosInBuffer = this.positionInBuffer(startNode, startPosition.remainder);
726
+ const endSplitPosInBuffer = this.positionInBuffer(startNode, endPosition.remainder);
727
+ if (startPosition.nodeStartOffset === offset) {
728
+ if (cnt === startNode.piece.length) { // delete node
729
+ const next = startNode.next();
730
+ rbDelete(this, startNode);
731
+ this.validateCRLFWithPrevNode(next);
732
+ this.computeBufferMetadata();
733
+ return;
734
+ }
735
+ this.deleteNodeHead(startNode, endSplitPosInBuffer);
736
+ this._searchCache.validate(offset);
737
+ this.validateCRLFWithPrevNode(startNode);
738
+ this.computeBufferMetadata();
739
+ return;
740
+ }
741
+ if (startPosition.nodeStartOffset + startNode.piece.length === offset + cnt) {
742
+ this.deleteNodeTail(startNode, startSplitPosInBuffer);
743
+ this.validateCRLFWithNextNode(startNode);
744
+ this.computeBufferMetadata();
745
+ return;
746
+ }
747
+ // delete content in the middle, this node will be splitted to nodes
748
+ this.shrinkNode(startNode, startSplitPosInBuffer, endSplitPosInBuffer);
749
+ this.computeBufferMetadata();
750
+ return;
751
+ }
752
+ const nodesToDel = [];
753
+ const startSplitPosInBuffer = this.positionInBuffer(startNode, startPosition.remainder);
754
+ this.deleteNodeTail(startNode, startSplitPosInBuffer);
755
+ this._searchCache.validate(offset);
756
+ if (startNode.piece.length === 0) {
757
+ nodesToDel.push(startNode);
758
+ }
759
+ // update last touched node
760
+ const endSplitPosInBuffer = this.positionInBuffer(endNode, endPosition.remainder);
761
+ this.deleteNodeHead(endNode, endSplitPosInBuffer);
762
+ if (endNode.piece.length === 0) {
763
+ nodesToDel.push(endNode);
764
+ }
765
+ // delete nodes in between
766
+ const secondNode = startNode.next();
767
+ for (let node = secondNode; node !== SENTINEL && node !== endNode; node = node.next()) {
768
+ nodesToDel.push(node);
769
+ }
770
+ const prev = startNode.piece.length === 0 ? startNode.prev() : startNode;
771
+ this.deleteNodes(nodesToDel);
772
+ this.validateCRLFWithNextNode(prev);
773
+ this.computeBufferMetadata();
774
+ }
775
+ insertContentToNodeLeft(value, node) {
776
+ // we are inserting content to the beginning of node
777
+ const nodesToDel = [];
778
+ if (this.shouldCheckCRLF() && this.endWithCR(value) && this.startWithLF(node)) {
779
+ // move `\n` to new node.
780
+ const piece = node.piece;
781
+ const newStart = { line: piece.start.line + 1, column: 0 };
782
+ const nPiece = new Piece(piece.bufferIndex, newStart, piece.end, this.getLineFeedCnt(piece.bufferIndex, newStart, piece.end), piece.length - 1);
783
+ node.piece = nPiece;
784
+ value += '\n';
785
+ updateTreeMetadata(this, node, -1, -1);
786
+ if (node.piece.length === 0) {
787
+ nodesToDel.push(node);
788
+ }
789
+ }
790
+ const newPieces = this.createNewPieces(value);
791
+ let newNode = this.rbInsertLeft(node, newPieces[newPieces.length - 1]);
792
+ for (let k = newPieces.length - 2; k >= 0; k--) {
793
+ newNode = this.rbInsertLeft(newNode, newPieces[k]);
794
+ }
795
+ this.validateCRLFWithPrevNode(newNode);
796
+ this.deleteNodes(nodesToDel);
797
+ }
798
+ insertContentToNodeRight(value, node) {
799
+ // we are inserting to the right of this node.
800
+ if (this.adjustCarriageReturnFromNext(value, node)) {
801
+ // move \n to the new node.
802
+ value += '\n';
803
+ }
804
+ const newPieces = this.createNewPieces(value);
805
+ const newNode = this.rbInsertRight(node, newPieces[0]);
806
+ let tmpNode = newNode;
807
+ for (let k = 1; k < newPieces.length; k++) {
808
+ tmpNode = this.rbInsertRight(tmpNode, newPieces[k]);
809
+ }
810
+ this.validateCRLFWithPrevNode(newNode);
811
+ }
812
+ positionInBuffer(node, remainder, ret) {
813
+ const piece = node.piece;
814
+ const bufferIndex = node.piece.bufferIndex;
815
+ const lineStarts = this._buffers[bufferIndex].lineStarts;
816
+ const startOffset = lineStarts[piece.start.line] + piece.start.column;
817
+ const offset = startOffset + remainder;
818
+ // binary search offset between startOffset and endOffset
819
+ let low = piece.start.line;
820
+ let high = piece.end.line;
821
+ let mid = 0;
822
+ let midStop = 0;
823
+ let midStart = 0;
824
+ while (low <= high) {
825
+ mid = low + ((high - low) / 2) | 0;
826
+ midStart = lineStarts[mid];
827
+ if (mid === high) {
828
+ break;
829
+ }
830
+ midStop = lineStarts[mid + 1];
831
+ if (offset < midStart) {
832
+ high = mid - 1;
833
+ }
834
+ else if (offset >= midStop) {
835
+ low = mid + 1;
836
+ }
837
+ else {
838
+ break;
839
+ }
840
+ }
841
+ if (ret) {
842
+ ret.line = mid;
843
+ ret.column = offset - midStart;
844
+ return null;
845
+ }
846
+ return {
847
+ line: mid,
848
+ column: offset - midStart
849
+ };
850
+ }
851
+ getLineFeedCnt(bufferIndex, start, end) {
852
+ // we don't need to worry about start: abc\r|\n, or abc|\r, or abc|\n, or abc|\r\n doesn't change the fact that, there is one line break after start.
853
+ // now let's take care of end: abc\r|\n, if end is in between \r and \n, we need to add line feed count by 1
854
+ if (end.column === 0) {
855
+ return end.line - start.line;
856
+ }
857
+ const lineStarts = this._buffers[bufferIndex].lineStarts;
858
+ if (end.line === lineStarts.length - 1) { // it means, there is no \n after end, otherwise, there will be one more lineStart.
859
+ return end.line - start.line;
860
+ }
861
+ const nextLineStartOffset = lineStarts[end.line + 1];
862
+ const endOffset = lineStarts[end.line] + end.column;
863
+ if (nextLineStartOffset > endOffset + 1) { // there are more than 1 character after end, which means it can't be \n
864
+ return end.line - start.line;
865
+ }
866
+ // endOffset + 1 === nextLineStartOffset
867
+ // character at endOffset is \n, so we check the character before first
868
+ // if character at endOffset is \r, end.column is 0 and we can't get here.
869
+ const previousCharOffset = endOffset - 1; // end.column > 0 so it's okay.
870
+ const buffer = this._buffers[bufferIndex].buffer;
871
+ if (buffer.charCodeAt(previousCharOffset) === 13) {
872
+ return end.line - start.line + 1;
873
+ }
874
+ else {
875
+ return end.line - start.line;
876
+ }
877
+ }
878
+ offsetInBuffer(bufferIndex, cursor) {
879
+ const lineStarts = this._buffers[bufferIndex].lineStarts;
880
+ return lineStarts[cursor.line] + cursor.column;
881
+ }
882
+ deleteNodes(nodes) {
883
+ for (let i = 0; i < nodes.length; i++) {
884
+ rbDelete(this, nodes[i]);
885
+ }
886
+ }
887
+ createNewPieces(text) {
888
+ if (text.length > AverageBufferSize) {
889
+ // the content is large, operations like substring, charCode becomes slow
890
+ // so here we split it into smaller chunks, just like what we did for CR/LF normalization
891
+ const newPieces = [];
892
+ while (text.length > AverageBufferSize) {
893
+ const lastChar = text.charCodeAt(AverageBufferSize - 1);
894
+ let splitText;
895
+ if (lastChar === 13 /* CharCode.CarriageReturn */ || (lastChar >= 0xD800 && lastChar <= 0xDBFF)) {
896
+ // last character is \r or a high surrogate => keep it back
897
+ splitText = text.substring(0, AverageBufferSize - 1);
898
+ text = text.substring(AverageBufferSize - 1);
899
+ }
900
+ else {
901
+ splitText = text.substring(0, AverageBufferSize);
902
+ text = text.substring(AverageBufferSize);
903
+ }
904
+ const lineStarts = createLineStartsFast(splitText);
905
+ newPieces.push(new Piece(this._buffers.length, /* buffer index */ { line: 0, column: 0 }, { line: lineStarts.length - 1, column: splitText.length - lineStarts[lineStarts.length - 1] }, lineStarts.length - 1, splitText.length));
906
+ this._buffers.push(new StringBuffer(splitText, lineStarts));
907
+ }
908
+ const lineStarts = createLineStartsFast(text);
909
+ newPieces.push(new Piece(this._buffers.length, /* buffer index */ { line: 0, column: 0 }, { line: lineStarts.length - 1, column: text.length - lineStarts[lineStarts.length - 1] }, lineStarts.length - 1, text.length));
910
+ this._buffers.push(new StringBuffer(text, lineStarts));
911
+ return newPieces;
912
+ }
913
+ let startOffset = this._buffers[0].buffer.length;
914
+ const lineStarts = createLineStartsFast(text, false);
915
+ let start = this._lastChangeBufferPos;
916
+ if (this._buffers[0].lineStarts[this._buffers[0].lineStarts.length - 1] === startOffset
917
+ && startOffset !== 0
918
+ && this.startWithLF(text)
919
+ && this.endWithCR(this._buffers[0].buffer) // todo, we can check this._lastChangeBufferPos's column as it's the last one
920
+ ) {
921
+ this._lastChangeBufferPos = { line: this._lastChangeBufferPos.line, column: this._lastChangeBufferPos.column + 1 };
922
+ start = this._lastChangeBufferPos;
923
+ for (let i = 0; i < lineStarts.length; i++) {
924
+ lineStarts[i] += startOffset + 1;
925
+ }
926
+ this._buffers[0].lineStarts = this._buffers[0].lineStarts.concat(lineStarts.slice(1));
927
+ this._buffers[0].buffer += '_' + text;
928
+ startOffset += 1;
929
+ }
930
+ else {
931
+ if (startOffset !== 0) {
932
+ for (let i = 0; i < lineStarts.length; i++) {
933
+ lineStarts[i] += startOffset;
934
+ }
935
+ }
936
+ this._buffers[0].lineStarts = this._buffers[0].lineStarts.concat(lineStarts.slice(1));
937
+ this._buffers[0].buffer += text;
938
+ }
939
+ const endOffset = this._buffers[0].buffer.length;
940
+ const endIndex = this._buffers[0].lineStarts.length - 1;
941
+ const endColumn = endOffset - this._buffers[0].lineStarts[endIndex];
942
+ const endPos = { line: endIndex, column: endColumn };
943
+ const newPiece = new Piece(0, /** todo@peng */ start, endPos, this.getLineFeedCnt(0, start, endPos), endOffset - startOffset);
944
+ this._lastChangeBufferPos = endPos;
945
+ return [newPiece];
946
+ }
947
+ getLineRawContent(lineNumber, endOffset = 0) {
948
+ let x = this.root;
949
+ let ret = '';
950
+ const cache = this._searchCache.get2(lineNumber);
951
+ if (cache) {
952
+ x = cache.node;
953
+ const prevAccumulatedValue = this.getAccumulatedValue(x, lineNumber - cache.nodeStartLineNumber - 1);
954
+ const buffer = this._buffers[x.piece.bufferIndex].buffer;
955
+ const startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start);
956
+ if (cache.nodeStartLineNumber + x.piece.lineFeedCnt === lineNumber) {
957
+ ret = buffer.substring(startOffset + prevAccumulatedValue, startOffset + x.piece.length);
958
+ }
959
+ else {
960
+ const accumulatedValue = this.getAccumulatedValue(x, lineNumber - cache.nodeStartLineNumber);
961
+ return buffer.substring(startOffset + prevAccumulatedValue, startOffset + accumulatedValue - endOffset);
962
+ }
963
+ }
964
+ else {
965
+ let nodeStartOffset = 0;
966
+ const originalLineNumber = lineNumber;
967
+ while (x !== SENTINEL) {
968
+ if (x.left !== SENTINEL && x.lf_left >= lineNumber - 1) {
969
+ x = x.left;
970
+ }
971
+ else if (x.lf_left + x.piece.lineFeedCnt > lineNumber - 1) {
972
+ const prevAccumulatedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2);
973
+ const accumulatedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 1);
974
+ const buffer = this._buffers[x.piece.bufferIndex].buffer;
975
+ const startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start);
976
+ nodeStartOffset += x.size_left;
977
+ this._searchCache.set({
978
+ node: x,
979
+ nodeStartOffset,
980
+ nodeStartLineNumber: originalLineNumber - (lineNumber - 1 - x.lf_left)
981
+ });
982
+ return buffer.substring(startOffset + prevAccumulatedValue, startOffset + accumulatedValue - endOffset);
983
+ }
984
+ else if (x.lf_left + x.piece.lineFeedCnt === lineNumber - 1) {
985
+ const prevAccumulatedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2);
986
+ const buffer = this._buffers[x.piece.bufferIndex].buffer;
987
+ const startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start);
988
+ ret = buffer.substring(startOffset + prevAccumulatedValue, startOffset + x.piece.length);
989
+ break;
990
+ }
991
+ else {
992
+ lineNumber -= x.lf_left + x.piece.lineFeedCnt;
993
+ nodeStartOffset += x.size_left + x.piece.length;
994
+ x = x.right;
995
+ }
996
+ }
997
+ }
998
+ // search in order, to find the node contains end column
999
+ x = x.next();
1000
+ while (x !== SENTINEL) {
1001
+ const buffer = this._buffers[x.piece.bufferIndex].buffer;
1002
+ if (x.piece.lineFeedCnt > 0) {
1003
+ const accumulatedValue = this.getAccumulatedValue(x, 0);
1004
+ const startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start);
1005
+ ret += buffer.substring(startOffset, startOffset + accumulatedValue - endOffset);
1006
+ return ret;
1007
+ }
1008
+ else {
1009
+ const startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start);
1010
+ ret += buffer.substr(startOffset, x.piece.length);
1011
+ }
1012
+ x = x.next();
1013
+ }
1014
+ return ret;
1015
+ }
1016
+ computeBufferMetadata() {
1017
+ let x = this.root;
1018
+ let lfCnt = 1;
1019
+ let len = 0;
1020
+ while (x !== SENTINEL) {
1021
+ lfCnt += x.lf_left + x.piece.lineFeedCnt;
1022
+ len += x.size_left + x.piece.length;
1023
+ x = x.right;
1024
+ }
1025
+ this._lineCnt = lfCnt;
1026
+ this._length = len;
1027
+ this._searchCache.validate(this._length);
1028
+ }
1029
+ // #region node operations
1030
+ getIndexOf(node, accumulatedValue) {
1031
+ const piece = node.piece;
1032
+ const pos = this.positionInBuffer(node, accumulatedValue);
1033
+ const lineCnt = pos.line - piece.start.line;
1034
+ if (this.offsetInBuffer(piece.bufferIndex, piece.end) - this.offsetInBuffer(piece.bufferIndex, piece.start) === accumulatedValue) {
1035
+ // we are checking the end of this node, so a CRLF check is necessary.
1036
+ const realLineCnt = this.getLineFeedCnt(node.piece.bufferIndex, piece.start, pos);
1037
+ if (realLineCnt !== lineCnt) {
1038
+ // aha yes, CRLF
1039
+ return { index: realLineCnt, remainder: 0 };
1040
+ }
1041
+ }
1042
+ return { index: lineCnt, remainder: pos.column };
1043
+ }
1044
+ getAccumulatedValue(node, index) {
1045
+ if (index < 0) {
1046
+ return 0;
1047
+ }
1048
+ const piece = node.piece;
1049
+ const lineStarts = this._buffers[piece.bufferIndex].lineStarts;
1050
+ const expectedLineStartIndex = piece.start.line + index + 1;
1051
+ if (expectedLineStartIndex > piece.end.line) {
1052
+ return lineStarts[piece.end.line] + piece.end.column - lineStarts[piece.start.line] - piece.start.column;
1053
+ }
1054
+ else {
1055
+ return lineStarts[expectedLineStartIndex] - lineStarts[piece.start.line] - piece.start.column;
1056
+ }
1057
+ }
1058
+ deleteNodeTail(node, pos) {
1059
+ const piece = node.piece;
1060
+ const originalLFCnt = piece.lineFeedCnt;
1061
+ const originalEndOffset = this.offsetInBuffer(piece.bufferIndex, piece.end);
1062
+ const newEnd = pos;
1063
+ const newEndOffset = this.offsetInBuffer(piece.bufferIndex, newEnd);
1064
+ const newLineFeedCnt = this.getLineFeedCnt(piece.bufferIndex, piece.start, newEnd);
1065
+ const lf_delta = newLineFeedCnt - originalLFCnt;
1066
+ const size_delta = newEndOffset - originalEndOffset;
1067
+ const newLength = piece.length + size_delta;
1068
+ node.piece = new Piece(piece.bufferIndex, piece.start, newEnd, newLineFeedCnt, newLength);
1069
+ updateTreeMetadata(this, node, size_delta, lf_delta);
1070
+ }
1071
+ deleteNodeHead(node, pos) {
1072
+ const piece = node.piece;
1073
+ const originalLFCnt = piece.lineFeedCnt;
1074
+ const originalStartOffset = this.offsetInBuffer(piece.bufferIndex, piece.start);
1075
+ const newStart = pos;
1076
+ const newLineFeedCnt = this.getLineFeedCnt(piece.bufferIndex, newStart, piece.end);
1077
+ const newStartOffset = this.offsetInBuffer(piece.bufferIndex, newStart);
1078
+ const lf_delta = newLineFeedCnt - originalLFCnt;
1079
+ const size_delta = originalStartOffset - newStartOffset;
1080
+ const newLength = piece.length + size_delta;
1081
+ node.piece = new Piece(piece.bufferIndex, newStart, piece.end, newLineFeedCnt, newLength);
1082
+ updateTreeMetadata(this, node, size_delta, lf_delta);
1083
+ }
1084
+ shrinkNode(node, start, end) {
1085
+ const piece = node.piece;
1086
+ const originalStartPos = piece.start;
1087
+ const originalEndPos = piece.end;
1088
+ // old piece, originalStartPos, start
1089
+ const oldLength = piece.length;
1090
+ const oldLFCnt = piece.lineFeedCnt;
1091
+ const newEnd = start;
1092
+ const newLineFeedCnt = this.getLineFeedCnt(piece.bufferIndex, piece.start, newEnd);
1093
+ const newLength = this.offsetInBuffer(piece.bufferIndex, start) - this.offsetInBuffer(piece.bufferIndex, originalStartPos);
1094
+ node.piece = new Piece(piece.bufferIndex, piece.start, newEnd, newLineFeedCnt, newLength);
1095
+ updateTreeMetadata(this, node, newLength - oldLength, newLineFeedCnt - oldLFCnt);
1096
+ // new right piece, end, originalEndPos
1097
+ const newPiece = new Piece(piece.bufferIndex, end, originalEndPos, this.getLineFeedCnt(piece.bufferIndex, end, originalEndPos), this.offsetInBuffer(piece.bufferIndex, originalEndPos) - this.offsetInBuffer(piece.bufferIndex, end));
1098
+ const newNode = this.rbInsertRight(node, newPiece);
1099
+ this.validateCRLFWithPrevNode(newNode);
1100
+ }
1101
+ appendToNode(node, value) {
1102
+ if (this.adjustCarriageReturnFromNext(value, node)) {
1103
+ value += '\n';
1104
+ }
1105
+ const hitCRLF = this.shouldCheckCRLF() && this.startWithLF(value) && this.endWithCR(node);
1106
+ const startOffset = this._buffers[0].buffer.length;
1107
+ this._buffers[0].buffer += value;
1108
+ const lineStarts = createLineStartsFast(value, false);
1109
+ for (let i = 0; i < lineStarts.length; i++) {
1110
+ lineStarts[i] += startOffset;
1111
+ }
1112
+ if (hitCRLF) {
1113
+ const prevStartOffset = this._buffers[0].lineStarts[this._buffers[0].lineStarts.length - 2];
1114
+ this._buffers[0].lineStarts.pop();
1115
+ // _lastChangeBufferPos is already wrong
1116
+ this._lastChangeBufferPos = { line: this._lastChangeBufferPos.line - 1, column: startOffset - prevStartOffset };
1117
+ }
1118
+ this._buffers[0].lineStarts = this._buffers[0].lineStarts.concat(lineStarts.slice(1));
1119
+ const endIndex = this._buffers[0].lineStarts.length - 1;
1120
+ const endColumn = this._buffers[0].buffer.length - this._buffers[0].lineStarts[endIndex];
1121
+ const newEnd = { line: endIndex, column: endColumn };
1122
+ const newLength = node.piece.length + value.length;
1123
+ const oldLineFeedCnt = node.piece.lineFeedCnt;
1124
+ const newLineFeedCnt = this.getLineFeedCnt(0, node.piece.start, newEnd);
1125
+ const lf_delta = newLineFeedCnt - oldLineFeedCnt;
1126
+ node.piece = new Piece(node.piece.bufferIndex, node.piece.start, newEnd, newLineFeedCnt, newLength);
1127
+ this._lastChangeBufferPos = newEnd;
1128
+ updateTreeMetadata(this, node, value.length, lf_delta);
1129
+ }
1130
+ nodeAt(offset) {
1131
+ let x = this.root;
1132
+ const cache = this._searchCache.get(offset);
1133
+ if (cache) {
1134
+ return {
1135
+ node: cache.node,
1136
+ nodeStartOffset: cache.nodeStartOffset,
1137
+ remainder: offset - cache.nodeStartOffset
1138
+ };
1139
+ }
1140
+ let nodeStartOffset = 0;
1141
+ while (x !== SENTINEL) {
1142
+ if (x.size_left > offset) {
1143
+ x = x.left;
1144
+ }
1145
+ else if (x.size_left + x.piece.length >= offset) {
1146
+ nodeStartOffset += x.size_left;
1147
+ const ret = {
1148
+ node: x,
1149
+ remainder: offset - x.size_left,
1150
+ nodeStartOffset
1151
+ };
1152
+ this._searchCache.set(ret);
1153
+ return ret;
1154
+ }
1155
+ else {
1156
+ offset -= x.size_left + x.piece.length;
1157
+ nodeStartOffset += x.size_left + x.piece.length;
1158
+ x = x.right;
1159
+ }
1160
+ }
1161
+ return null;
1162
+ }
1163
+ nodeAt2(lineNumber, column) {
1164
+ let x = this.root;
1165
+ let nodeStartOffset = 0;
1166
+ while (x !== SENTINEL) {
1167
+ if (x.left !== SENTINEL && x.lf_left >= lineNumber - 1) {
1168
+ x = x.left;
1169
+ }
1170
+ else if (x.lf_left + x.piece.lineFeedCnt > lineNumber - 1) {
1171
+ const prevAccumualtedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2);
1172
+ const accumulatedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 1);
1173
+ nodeStartOffset += x.size_left;
1174
+ return {
1175
+ node: x,
1176
+ remainder: Math.min(prevAccumualtedValue + column - 1, accumulatedValue),
1177
+ nodeStartOffset
1178
+ };
1179
+ }
1180
+ else if (x.lf_left + x.piece.lineFeedCnt === lineNumber - 1) {
1181
+ const prevAccumualtedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2);
1182
+ if (prevAccumualtedValue + column - 1 <= x.piece.length) {
1183
+ return {
1184
+ node: x,
1185
+ remainder: prevAccumualtedValue + column - 1,
1186
+ nodeStartOffset
1187
+ };
1188
+ }
1189
+ else {
1190
+ column -= x.piece.length - prevAccumualtedValue;
1191
+ break;
1192
+ }
1193
+ }
1194
+ else {
1195
+ lineNumber -= x.lf_left + x.piece.lineFeedCnt;
1196
+ nodeStartOffset += x.size_left + x.piece.length;
1197
+ x = x.right;
1198
+ }
1199
+ }
1200
+ // search in order, to find the node contains position.column
1201
+ x = x.next();
1202
+ while (x !== SENTINEL) {
1203
+ if (x.piece.lineFeedCnt > 0) {
1204
+ const accumulatedValue = this.getAccumulatedValue(x, 0);
1205
+ const nodeStartOffset = this.offsetOfNode(x);
1206
+ return {
1207
+ node: x,
1208
+ remainder: Math.min(column - 1, accumulatedValue),
1209
+ nodeStartOffset
1210
+ };
1211
+ }
1212
+ else {
1213
+ if (x.piece.length >= column - 1) {
1214
+ const nodeStartOffset = this.offsetOfNode(x);
1215
+ return {
1216
+ node: x,
1217
+ remainder: column - 1,
1218
+ nodeStartOffset
1219
+ };
1220
+ }
1221
+ else {
1222
+ column -= x.piece.length;
1223
+ }
1224
+ }
1225
+ x = x.next();
1226
+ }
1227
+ return null;
1228
+ }
1229
+ nodeCharCodeAt(node, offset) {
1230
+ if (node.piece.lineFeedCnt < 1) {
1231
+ return -1;
1232
+ }
1233
+ const buffer = this._buffers[node.piece.bufferIndex];
1234
+ const newOffset = this.offsetInBuffer(node.piece.bufferIndex, node.piece.start) + offset;
1235
+ return buffer.buffer.charCodeAt(newOffset);
1236
+ }
1237
+ offsetOfNode(node) {
1238
+ if (!node) {
1239
+ return 0;
1240
+ }
1241
+ let pos = node.size_left;
1242
+ while (node !== this.root) {
1243
+ if (node.parent.right === node) {
1244
+ pos += node.parent.size_left + node.parent.piece.length;
1245
+ }
1246
+ node = node.parent;
1247
+ }
1248
+ return pos;
1249
+ }
1250
+ // #endregion
1251
+ // #region CRLF
1252
+ shouldCheckCRLF() {
1253
+ return !(this._EOLNormalized && this._EOL === '\n');
1254
+ }
1255
+ startWithLF(val) {
1256
+ if (typeof val === 'string') {
1257
+ return val.charCodeAt(0) === 10;
1258
+ }
1259
+ if (val === SENTINEL || val.piece.lineFeedCnt === 0) {
1260
+ return false;
1261
+ }
1262
+ const piece = val.piece;
1263
+ const lineStarts = this._buffers[piece.bufferIndex].lineStarts;
1264
+ const line = piece.start.line;
1265
+ const startOffset = lineStarts[line] + piece.start.column;
1266
+ if (line === lineStarts.length - 1) {
1267
+ // last line, so there is no line feed at the end of this line
1268
+ return false;
1269
+ }
1270
+ const nextLineOffset = lineStarts[line + 1];
1271
+ if (nextLineOffset > startOffset + 1) {
1272
+ return false;
1273
+ }
1274
+ return this._buffers[piece.bufferIndex].buffer.charCodeAt(startOffset) === 10;
1275
+ }
1276
+ endWithCR(val) {
1277
+ if (typeof val === 'string') {
1278
+ return val.charCodeAt(val.length - 1) === 13;
1279
+ }
1280
+ if (val === SENTINEL || val.piece.lineFeedCnt === 0) {
1281
+ return false;
1282
+ }
1283
+ return this.nodeCharCodeAt(val, val.piece.length - 1) === 13;
1284
+ }
1285
+ validateCRLFWithPrevNode(nextNode) {
1286
+ if (this.shouldCheckCRLF() && this.startWithLF(nextNode)) {
1287
+ const node = nextNode.prev();
1288
+ if (this.endWithCR(node)) {
1289
+ this.fixCRLF(node, nextNode);
1290
+ }
1291
+ }
1292
+ }
1293
+ validateCRLFWithNextNode(node) {
1294
+ if (this.shouldCheckCRLF() && this.endWithCR(node)) {
1295
+ const nextNode = node.next();
1296
+ if (this.startWithLF(nextNode)) {
1297
+ this.fixCRLF(node, nextNode);
1298
+ }
1299
+ }
1300
+ }
1301
+ fixCRLF(prev, next) {
1302
+ const nodesToDel = [];
1303
+ // update node
1304
+ const lineStarts = this._buffers[prev.piece.bufferIndex].lineStarts;
1305
+ let newEnd;
1306
+ if (prev.piece.end.column === 0) {
1307
+ // it means, last line ends with \r, not \r\n
1308
+ newEnd = { line: prev.piece.end.line - 1, column: lineStarts[prev.piece.end.line] - lineStarts[prev.piece.end.line - 1] - 1 };
1309
+ }
1310
+ else {
1311
+ // \r\n
1312
+ newEnd = { line: prev.piece.end.line, column: prev.piece.end.column - 1 };
1313
+ }
1314
+ const prevNewLength = prev.piece.length - 1;
1315
+ const prevNewLFCnt = prev.piece.lineFeedCnt - 1;
1316
+ prev.piece = new Piece(prev.piece.bufferIndex, prev.piece.start, newEnd, prevNewLFCnt, prevNewLength);
1317
+ updateTreeMetadata(this, prev, -1, -1);
1318
+ if (prev.piece.length === 0) {
1319
+ nodesToDel.push(prev);
1320
+ }
1321
+ // update nextNode
1322
+ const newStart = { line: next.piece.start.line + 1, column: 0 };
1323
+ const newLength = next.piece.length - 1;
1324
+ const newLineFeedCnt = this.getLineFeedCnt(next.piece.bufferIndex, newStart, next.piece.end);
1325
+ next.piece = new Piece(next.piece.bufferIndex, newStart, next.piece.end, newLineFeedCnt, newLength);
1326
+ updateTreeMetadata(this, next, -1, -1);
1327
+ if (next.piece.length === 0) {
1328
+ nodesToDel.push(next);
1329
+ }
1330
+ // create new piece which contains \r\n
1331
+ const pieces = this.createNewPieces('\r\n');
1332
+ this.rbInsertRight(prev, pieces[0]);
1333
+ // delete empty nodes
1334
+ for (let i = 0; i < nodesToDel.length; i++) {
1335
+ rbDelete(this, nodesToDel[i]);
1336
+ }
1337
+ }
1338
+ adjustCarriageReturnFromNext(value, node) {
1339
+ if (this.shouldCheckCRLF() && this.endWithCR(value)) {
1340
+ const nextNode = node.next();
1341
+ if (this.startWithLF(nextNode)) {
1342
+ // move `\n` forward
1343
+ value += '\n';
1344
+ if (nextNode.piece.length === 1) {
1345
+ rbDelete(this, nextNode);
1346
+ }
1347
+ else {
1348
+ const piece = nextNode.piece;
1349
+ const newStart = { line: piece.start.line + 1, column: 0 };
1350
+ const newLength = piece.length - 1;
1351
+ const newLineFeedCnt = this.getLineFeedCnt(piece.bufferIndex, newStart, piece.end);
1352
+ nextNode.piece = new Piece(piece.bufferIndex, newStart, piece.end, newLineFeedCnt, newLength);
1353
+ updateTreeMetadata(this, nextNode, -1, -1);
1354
+ }
1355
+ return true;
1356
+ }
1357
+ }
1358
+ return false;
1359
+ }
1360
+ // #endregion
1361
+ // #endregion
1362
+ // #region Tree operations
1363
+ iterate(node, callback) {
1364
+ if (node === SENTINEL) {
1365
+ return callback(SENTINEL);
1366
+ }
1367
+ const leftRet = this.iterate(node.left, callback);
1368
+ if (!leftRet) {
1369
+ return leftRet;
1370
+ }
1371
+ return callback(node) && this.iterate(node.right, callback);
1372
+ }
1373
+ getNodeContent(node) {
1374
+ if (node === SENTINEL) {
1375
+ return '';
1376
+ }
1377
+ const buffer = this._buffers[node.piece.bufferIndex];
1378
+ const piece = node.piece;
1379
+ const startOffset = this.offsetInBuffer(piece.bufferIndex, piece.start);
1380
+ const endOffset = this.offsetInBuffer(piece.bufferIndex, piece.end);
1381
+ const currentContent = buffer.buffer.substring(startOffset, endOffset);
1382
+ return currentContent;
1383
+ }
1384
+ getPieceContent(piece) {
1385
+ const buffer = this._buffers[piece.bufferIndex];
1386
+ const startOffset = this.offsetInBuffer(piece.bufferIndex, piece.start);
1387
+ const endOffset = this.offsetInBuffer(piece.bufferIndex, piece.end);
1388
+ const currentContent = buffer.buffer.substring(startOffset, endOffset);
1389
+ return currentContent;
1390
+ }
1391
+ /**
1392
+ * node node
1393
+ * / \ / \
1394
+ * a b <---- a b
1395
+ * /
1396
+ * z
1397
+ */
1398
+ rbInsertRight(node, p) {
1399
+ const z = new TreeNode(p, 1 /* NodeColor.Red */);
1400
+ z.left = SENTINEL;
1401
+ z.right = SENTINEL;
1402
+ z.parent = SENTINEL;
1403
+ z.size_left = 0;
1404
+ z.lf_left = 0;
1405
+ const x = this.root;
1406
+ if (x === SENTINEL) {
1407
+ this.root = z;
1408
+ z.color = 0 /* NodeColor.Black */;
1409
+ }
1410
+ else if (node.right === SENTINEL) {
1411
+ node.right = z;
1412
+ z.parent = node;
1413
+ }
1414
+ else {
1415
+ const nextNode = leftest(node.right);
1416
+ nextNode.left = z;
1417
+ z.parent = nextNode;
1418
+ }
1419
+ fixInsert(this, z);
1420
+ return z;
1421
+ }
1422
+ /**
1423
+ * node node
1424
+ * / \ / \
1425
+ * a b ----> a b
1426
+ * \
1427
+ * z
1428
+ */
1429
+ rbInsertLeft(node, p) {
1430
+ const z = new TreeNode(p, 1 /* NodeColor.Red */);
1431
+ z.left = SENTINEL;
1432
+ z.right = SENTINEL;
1433
+ z.parent = SENTINEL;
1434
+ z.size_left = 0;
1435
+ z.lf_left = 0;
1436
+ if (this.root === SENTINEL) {
1437
+ this.root = z;
1438
+ z.color = 0 /* NodeColor.Black */;
1439
+ }
1440
+ else if (node.left === SENTINEL) {
1441
+ node.left = z;
1442
+ z.parent = node;
1443
+ }
1444
+ else {
1445
+ const prevNode = righttest(node.left); // a
1446
+ prevNode.right = z;
1447
+ z.parent = prevNode;
1448
+ }
1449
+ fixInsert(this, z);
1450
+ return z;
1451
+ }
1452
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.js ADDED
@@ -0,0 +1,455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { Emitter } from '../../../../base/common/event.js';
6
+ import * as strings from '../../../../base/common/strings.js';
7
+ import { Range } from '../../core/range.js';
8
+ import { ApplyEditsResult } from '../../model.js';
9
+ import { PieceTreeBase } from './pieceTreeBase.js';
10
+ import { countEOL } from '../../core/eolCounter.js';
11
+ import { TextChange } from '../../core/textChange.js';
12
+ import { Disposable } from '../../../../base/common/lifecycle.js';
13
+ export class PieceTreeTextBuffer extends Disposable {
14
+ constructor(chunks, BOM, eol, containsRTL, containsUnusualLineTerminators, isBasicASCII, eolNormalized) {
15
+ super();
16
+ this._onDidChangeContent = this._register(new Emitter());
17
+ this._BOM = BOM;
18
+ this._mightContainNonBasicASCII = !isBasicASCII;
19
+ this._mightContainRTL = containsRTL;
20
+ this._mightContainUnusualLineTerminators = containsUnusualLineTerminators;
21
+ this._pieceTree = new PieceTreeBase(chunks, eol, eolNormalized);
22
+ }
23
+ mightContainRTL() {
24
+ return this._mightContainRTL;
25
+ }
26
+ mightContainUnusualLineTerminators() {
27
+ return this._mightContainUnusualLineTerminators;
28
+ }
29
+ resetMightContainUnusualLineTerminators() {
30
+ this._mightContainUnusualLineTerminators = false;
31
+ }
32
+ mightContainNonBasicASCII() {
33
+ return this._mightContainNonBasicASCII;
34
+ }
35
+ getBOM() {
36
+ return this._BOM;
37
+ }
38
+ getEOL() {
39
+ return this._pieceTree.getEOL();
40
+ }
41
+ createSnapshot(preserveBOM) {
42
+ return this._pieceTree.createSnapshot(preserveBOM ? this._BOM : '');
43
+ }
44
+ getOffsetAt(lineNumber, column) {
45
+ return this._pieceTree.getOffsetAt(lineNumber, column);
46
+ }
47
+ getPositionAt(offset) {
48
+ return this._pieceTree.getPositionAt(offset);
49
+ }
50
+ getRangeAt(start, length) {
51
+ const end = start + length;
52
+ const startPosition = this.getPositionAt(start);
53
+ const endPosition = this.getPositionAt(end);
54
+ return new Range(startPosition.lineNumber, startPosition.column, endPosition.lineNumber, endPosition.column);
55
+ }
56
+ getValueInRange(range, eol = 0 /* EndOfLinePreference.TextDefined */) {
57
+ if (range.isEmpty()) {
58
+ return '';
59
+ }
60
+ const lineEnding = this._getEndOfLine(eol);
61
+ return this._pieceTree.getValueInRange(range, lineEnding);
62
+ }
63
+ getValueLengthInRange(range, eol = 0 /* EndOfLinePreference.TextDefined */) {
64
+ if (range.isEmpty()) {
65
+ return 0;
66
+ }
67
+ if (range.startLineNumber === range.endLineNumber) {
68
+ return (range.endColumn - range.startColumn);
69
+ }
70
+ const startOffset = this.getOffsetAt(range.startLineNumber, range.startColumn);
71
+ const endOffset = this.getOffsetAt(range.endLineNumber, range.endColumn);
72
+ // offsets use the text EOL, so we need to compensate for length differences
73
+ // if the requested EOL doesn't match the text EOL
74
+ let eolOffsetCompensation = 0;
75
+ const desiredEOL = this._getEndOfLine(eol);
76
+ const actualEOL = this.getEOL();
77
+ if (desiredEOL.length !== actualEOL.length) {
78
+ const delta = desiredEOL.length - actualEOL.length;
79
+ const eolCount = range.endLineNumber - range.startLineNumber;
80
+ eolOffsetCompensation = delta * eolCount;
81
+ }
82
+ return endOffset - startOffset + eolOffsetCompensation;
83
+ }
84
+ getCharacterCountInRange(range, eol = 0 /* EndOfLinePreference.TextDefined */) {
85
+ if (this._mightContainNonBasicASCII) {
86
+ // we must count by iterating
87
+ let result = 0;
88
+ const fromLineNumber = range.startLineNumber;
89
+ const toLineNumber = range.endLineNumber;
90
+ for (let lineNumber = fromLineNumber; lineNumber <= toLineNumber; lineNumber++) {
91
+ const lineContent = this.getLineContent(lineNumber);
92
+ const fromOffset = (lineNumber === fromLineNumber ? range.startColumn - 1 : 0);
93
+ const toOffset = (lineNumber === toLineNumber ? range.endColumn - 1 : lineContent.length);
94
+ for (let offset = fromOffset; offset < toOffset; offset++) {
95
+ if (strings.isHighSurrogate(lineContent.charCodeAt(offset))) {
96
+ result = result + 1;
97
+ offset = offset + 1;
98
+ }
99
+ else {
100
+ result = result + 1;
101
+ }
102
+ }
103
+ }
104
+ result += this._getEndOfLine(eol).length * (toLineNumber - fromLineNumber);
105
+ return result;
106
+ }
107
+ return this.getValueLengthInRange(range, eol);
108
+ }
109
+ getLength() {
110
+ return this._pieceTree.getLength();
111
+ }
112
+ getLineCount() {
113
+ return this._pieceTree.getLineCount();
114
+ }
115
+ getLinesContent() {
116
+ return this._pieceTree.getLinesContent();
117
+ }
118
+ getLineContent(lineNumber) {
119
+ return this._pieceTree.getLineContent(lineNumber);
120
+ }
121
+ getLineCharCode(lineNumber, index) {
122
+ return this._pieceTree.getLineCharCode(lineNumber, index);
123
+ }
124
+ getLineLength(lineNumber) {
125
+ return this._pieceTree.getLineLength(lineNumber);
126
+ }
127
+ getLineFirstNonWhitespaceColumn(lineNumber) {
128
+ const result = strings.firstNonWhitespaceIndex(this.getLineContent(lineNumber));
129
+ if (result === -1) {
130
+ return 0;
131
+ }
132
+ return result + 1;
133
+ }
134
+ getLineLastNonWhitespaceColumn(lineNumber) {
135
+ const result = strings.lastNonWhitespaceIndex(this.getLineContent(lineNumber));
136
+ if (result === -1) {
137
+ return 0;
138
+ }
139
+ return result + 2;
140
+ }
141
+ _getEndOfLine(eol) {
142
+ switch (eol) {
143
+ case 1 /* EndOfLinePreference.LF */:
144
+ return '\n';
145
+ case 2 /* EndOfLinePreference.CRLF */:
146
+ return '\r\n';
147
+ case 0 /* EndOfLinePreference.TextDefined */:
148
+ return this.getEOL();
149
+ default:
150
+ throw new Error('Unknown EOL preference');
151
+ }
152
+ }
153
+ setEOL(newEOL) {
154
+ this._pieceTree.setEOL(newEOL);
155
+ }
156
+ applyEdits(rawOperations, recordTrimAutoWhitespace, computeUndoEdits) {
157
+ let mightContainRTL = this._mightContainRTL;
158
+ let mightContainUnusualLineTerminators = this._mightContainUnusualLineTerminators;
159
+ let mightContainNonBasicASCII = this._mightContainNonBasicASCII;
160
+ let canReduceOperations = true;
161
+ let operations = [];
162
+ for (let i = 0; i < rawOperations.length; i++) {
163
+ const op = rawOperations[i];
164
+ if (canReduceOperations && op._isTracked) {
165
+ canReduceOperations = false;
166
+ }
167
+ const validatedRange = op.range;
168
+ if (op.text) {
169
+ let textMightContainNonBasicASCII = true;
170
+ if (!mightContainNonBasicASCII) {
171
+ textMightContainNonBasicASCII = !strings.isBasicASCII(op.text);
172
+ mightContainNonBasicASCII = textMightContainNonBasicASCII;
173
+ }
174
+ if (!mightContainRTL && textMightContainNonBasicASCII) {
175
+ // check if the new inserted text contains RTL
176
+ mightContainRTL = strings.containsRTL(op.text);
177
+ }
178
+ if (!mightContainUnusualLineTerminators && textMightContainNonBasicASCII) {
179
+ // check if the new inserted text contains unusual line terminators
180
+ mightContainUnusualLineTerminators = strings.containsUnusualLineTerminators(op.text);
181
+ }
182
+ }
183
+ let validText = '';
184
+ let eolCount = 0;
185
+ let firstLineLength = 0;
186
+ let lastLineLength = 0;
187
+ if (op.text) {
188
+ let strEOL;
189
+ [eolCount, firstLineLength, lastLineLength, strEOL] = countEOL(op.text);
190
+ const bufferEOL = this.getEOL();
191
+ const expectedStrEOL = (bufferEOL === '\r\n' ? 2 /* StringEOL.CRLF */ : 1 /* StringEOL.LF */);
192
+ if (strEOL === 0 /* StringEOL.Unknown */ || strEOL === expectedStrEOL) {
193
+ validText = op.text;
194
+ }
195
+ else {
196
+ validText = op.text.replace(/\r\n|\r|\n/g, bufferEOL);
197
+ }
198
+ }
199
+ operations[i] = {
200
+ sortIndex: i,
201
+ identifier: op.identifier || null,
202
+ range: validatedRange,
203
+ rangeOffset: this.getOffsetAt(validatedRange.startLineNumber, validatedRange.startColumn),
204
+ rangeLength: this.getValueLengthInRange(validatedRange),
205
+ text: validText,
206
+ eolCount: eolCount,
207
+ firstLineLength: firstLineLength,
208
+ lastLineLength: lastLineLength,
209
+ forceMoveMarkers: Boolean(op.forceMoveMarkers),
210
+ isAutoWhitespaceEdit: op.isAutoWhitespaceEdit || false
211
+ };
212
+ }
213
+ // Sort operations ascending
214
+ operations.sort(PieceTreeTextBuffer._sortOpsAscending);
215
+ let hasTouchingRanges = false;
216
+ for (let i = 0, count = operations.length - 1; i < count; i++) {
217
+ const rangeEnd = operations[i].range.getEndPosition();
218
+ const nextRangeStart = operations[i + 1].range.getStartPosition();
219
+ if (nextRangeStart.isBeforeOrEqual(rangeEnd)) {
220
+ if (nextRangeStart.isBefore(rangeEnd)) {
221
+ // overlapping ranges
222
+ throw new Error('Overlapping ranges are not allowed!');
223
+ }
224
+ hasTouchingRanges = true;
225
+ }
226
+ }
227
+ if (canReduceOperations) {
228
+ operations = this._reduceOperations(operations);
229
+ }
230
+ // Delta encode operations
231
+ const reverseRanges = (computeUndoEdits || recordTrimAutoWhitespace ? PieceTreeTextBuffer._getInverseEditRanges(operations) : []);
232
+ const newTrimAutoWhitespaceCandidates = [];
233
+ if (recordTrimAutoWhitespace) {
234
+ for (let i = 0; i < operations.length; i++) {
235
+ const op = operations[i];
236
+ const reverseRange = reverseRanges[i];
237
+ if (op.isAutoWhitespaceEdit && op.range.isEmpty()) {
238
+ // Record already the future line numbers that might be auto whitespace removal candidates on next edit
239
+ for (let lineNumber = reverseRange.startLineNumber; lineNumber <= reverseRange.endLineNumber; lineNumber++) {
240
+ let currentLineContent = '';
241
+ if (lineNumber === reverseRange.startLineNumber) {
242
+ currentLineContent = this.getLineContent(op.range.startLineNumber);
243
+ if (strings.firstNonWhitespaceIndex(currentLineContent) !== -1) {
244
+ continue;
245
+ }
246
+ }
247
+ newTrimAutoWhitespaceCandidates.push({ lineNumber: lineNumber, oldContent: currentLineContent });
248
+ }
249
+ }
250
+ }
251
+ }
252
+ let reverseOperations = null;
253
+ if (computeUndoEdits) {
254
+ let reverseRangeDeltaOffset = 0;
255
+ reverseOperations = [];
256
+ for (let i = 0; i < operations.length; i++) {
257
+ const op = operations[i];
258
+ const reverseRange = reverseRanges[i];
259
+ const bufferText = this.getValueInRange(op.range);
260
+ const reverseRangeOffset = op.rangeOffset + reverseRangeDeltaOffset;
261
+ reverseRangeDeltaOffset += (op.text.length - bufferText.length);
262
+ reverseOperations[i] = {
263
+ sortIndex: op.sortIndex,
264
+ identifier: op.identifier,
265
+ range: reverseRange,
266
+ text: bufferText,
267
+ textChange: new TextChange(op.rangeOffset, bufferText, reverseRangeOffset, op.text)
268
+ };
269
+ }
270
+ // Can only sort reverse operations when the order is not significant
271
+ if (!hasTouchingRanges) {
272
+ reverseOperations.sort((a, b) => a.sortIndex - b.sortIndex);
273
+ }
274
+ }
275
+ this._mightContainRTL = mightContainRTL;
276
+ this._mightContainUnusualLineTerminators = mightContainUnusualLineTerminators;
277
+ this._mightContainNonBasicASCII = mightContainNonBasicASCII;
278
+ const contentChanges = this._doApplyEdits(operations);
279
+ let trimAutoWhitespaceLineNumbers = null;
280
+ if (recordTrimAutoWhitespace && newTrimAutoWhitespaceCandidates.length > 0) {
281
+ // sort line numbers auto whitespace removal candidates for next edit descending
282
+ newTrimAutoWhitespaceCandidates.sort((a, b) => b.lineNumber - a.lineNumber);
283
+ trimAutoWhitespaceLineNumbers = [];
284
+ for (let i = 0, len = newTrimAutoWhitespaceCandidates.length; i < len; i++) {
285
+ const lineNumber = newTrimAutoWhitespaceCandidates[i].lineNumber;
286
+ if (i > 0 && newTrimAutoWhitespaceCandidates[i - 1].lineNumber === lineNumber) {
287
+ // Do not have the same line number twice
288
+ continue;
289
+ }
290
+ const prevContent = newTrimAutoWhitespaceCandidates[i].oldContent;
291
+ const lineContent = this.getLineContent(lineNumber);
292
+ if (lineContent.length === 0 || lineContent === prevContent || strings.firstNonWhitespaceIndex(lineContent) !== -1) {
293
+ continue;
294
+ }
295
+ trimAutoWhitespaceLineNumbers.push(lineNumber);
296
+ }
297
+ }
298
+ this._onDidChangeContent.fire();
299
+ return new ApplyEditsResult(reverseOperations, contentChanges, trimAutoWhitespaceLineNumbers);
300
+ }
301
+ /**
302
+ * Transform operations such that they represent the same logic edit,
303
+ * but that they also do not cause OOM crashes.
304
+ */
305
+ _reduceOperations(operations) {
306
+ if (operations.length < 1000) {
307
+ // We know from empirical testing that a thousand edits work fine regardless of their shape.
308
+ return operations;
309
+ }
310
+ // At one point, due to how events are emitted and how each operation is handled,
311
+ // some operations can trigger a high amount of temporary string allocations,
312
+ // that will immediately get edited again.
313
+ // e.g. a formatter inserting ridiculous ammounts of \n on a model with a single line
314
+ // Therefore, the strategy is to collapse all the operations into a huge single edit operation
315
+ return [this._toSingleEditOperation(operations)];
316
+ }
317
+ _toSingleEditOperation(operations) {
318
+ let forceMoveMarkers = false;
319
+ const firstEditRange = operations[0].range;
320
+ const lastEditRange = operations[operations.length - 1].range;
321
+ const entireEditRange = new Range(firstEditRange.startLineNumber, firstEditRange.startColumn, lastEditRange.endLineNumber, lastEditRange.endColumn);
322
+ let lastEndLineNumber = firstEditRange.startLineNumber;
323
+ let lastEndColumn = firstEditRange.startColumn;
324
+ const result = [];
325
+ for (let i = 0, len = operations.length; i < len; i++) {
326
+ const operation = operations[i];
327
+ const range = operation.range;
328
+ forceMoveMarkers = forceMoveMarkers || operation.forceMoveMarkers;
329
+ // (1) -- Push old text
330
+ result.push(this.getValueInRange(new Range(lastEndLineNumber, lastEndColumn, range.startLineNumber, range.startColumn)));
331
+ // (2) -- Push new text
332
+ if (operation.text.length > 0) {
333
+ result.push(operation.text);
334
+ }
335
+ lastEndLineNumber = range.endLineNumber;
336
+ lastEndColumn = range.endColumn;
337
+ }
338
+ const text = result.join('');
339
+ const [eolCount, firstLineLength, lastLineLength] = countEOL(text);
340
+ return {
341
+ sortIndex: 0,
342
+ identifier: operations[0].identifier,
343
+ range: entireEditRange,
344
+ rangeOffset: this.getOffsetAt(entireEditRange.startLineNumber, entireEditRange.startColumn),
345
+ rangeLength: this.getValueLengthInRange(entireEditRange, 0 /* EndOfLinePreference.TextDefined */),
346
+ text: text,
347
+ eolCount: eolCount,
348
+ firstLineLength: firstLineLength,
349
+ lastLineLength: lastLineLength,
350
+ forceMoveMarkers: forceMoveMarkers,
351
+ isAutoWhitespaceEdit: false
352
+ };
353
+ }
354
+ _doApplyEdits(operations) {
355
+ operations.sort(PieceTreeTextBuffer._sortOpsDescending);
356
+ const contentChanges = [];
357
+ // operations are from bottom to top
358
+ for (let i = 0; i < operations.length; i++) {
359
+ const op = operations[i];
360
+ const startLineNumber = op.range.startLineNumber;
361
+ const startColumn = op.range.startColumn;
362
+ const endLineNumber = op.range.endLineNumber;
363
+ const endColumn = op.range.endColumn;
364
+ if (startLineNumber === endLineNumber && startColumn === endColumn && op.text.length === 0) {
365
+ // no-op
366
+ continue;
367
+ }
368
+ if (op.text) {
369
+ // replacement
370
+ this._pieceTree.delete(op.rangeOffset, op.rangeLength);
371
+ this._pieceTree.insert(op.rangeOffset, op.text, true);
372
+ }
373
+ else {
374
+ // deletion
375
+ this._pieceTree.delete(op.rangeOffset, op.rangeLength);
376
+ }
377
+ const contentChangeRange = new Range(startLineNumber, startColumn, endLineNumber, endColumn);
378
+ contentChanges.push({
379
+ range: contentChangeRange,
380
+ rangeLength: op.rangeLength,
381
+ text: op.text,
382
+ rangeOffset: op.rangeOffset,
383
+ forceMoveMarkers: op.forceMoveMarkers
384
+ });
385
+ }
386
+ return contentChanges;
387
+ }
388
+ findMatchesLineByLine(searchRange, searchData, captureMatches, limitResultCount) {
389
+ return this._pieceTree.findMatchesLineByLine(searchRange, searchData, captureMatches, limitResultCount);
390
+ }
391
+ /**
392
+ * Assumes `operations` are validated and sorted ascending
393
+ */
394
+ static _getInverseEditRanges(operations) {
395
+ const result = [];
396
+ let prevOpEndLineNumber = 0;
397
+ let prevOpEndColumn = 0;
398
+ let prevOp = null;
399
+ for (let i = 0, len = operations.length; i < len; i++) {
400
+ const op = operations[i];
401
+ let startLineNumber;
402
+ let startColumn;
403
+ if (prevOp) {
404
+ if (prevOp.range.endLineNumber === op.range.startLineNumber) {
405
+ startLineNumber = prevOpEndLineNumber;
406
+ startColumn = prevOpEndColumn + (op.range.startColumn - prevOp.range.endColumn);
407
+ }
408
+ else {
409
+ startLineNumber = prevOpEndLineNumber + (op.range.startLineNumber - prevOp.range.endLineNumber);
410
+ startColumn = op.range.startColumn;
411
+ }
412
+ }
413
+ else {
414
+ startLineNumber = op.range.startLineNumber;
415
+ startColumn = op.range.startColumn;
416
+ }
417
+ let resultRange;
418
+ if (op.text.length > 0) {
419
+ // the operation inserts something
420
+ const lineCount = op.eolCount + 1;
421
+ if (lineCount === 1) {
422
+ // single line insert
423
+ resultRange = new Range(startLineNumber, startColumn, startLineNumber, startColumn + op.firstLineLength);
424
+ }
425
+ else {
426
+ // multi line insert
427
+ resultRange = new Range(startLineNumber, startColumn, startLineNumber + lineCount - 1, op.lastLineLength + 1);
428
+ }
429
+ }
430
+ else {
431
+ // There is nothing to insert
432
+ resultRange = new Range(startLineNumber, startColumn, startLineNumber, startColumn);
433
+ }
434
+ prevOpEndLineNumber = resultRange.endLineNumber;
435
+ prevOpEndColumn = resultRange.endColumn;
436
+ result.push(resultRange);
437
+ prevOp = op;
438
+ }
439
+ return result;
440
+ }
441
+ static _sortOpsAscending(a, b) {
442
+ const r = Range.compareRangesUsingEnds(a.range, b.range);
443
+ if (r === 0) {
444
+ return a.sortIndex - b.sortIndex;
445
+ }
446
+ return r;
447
+ }
448
+ static _sortOpsDescending(a, b) {
449
+ const r = Range.compareRangesUsingEnds(a.range, b.range);
450
+ if (r === 0) {
451
+ return b.sortIndex - a.sortIndex;
452
+ }
453
+ return -r;
454
+ }
455
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.js ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import * as strings from '../../../../base/common/strings.js';
6
+ import { StringBuffer, createLineStarts, createLineStartsFast } from './pieceTreeBase.js';
7
+ import { PieceTreeTextBuffer } from './pieceTreeTextBuffer.js';
8
+ class PieceTreeTextBufferFactory {
9
+ constructor(_chunks, _bom, _cr, _lf, _crlf, _containsRTL, _containsUnusualLineTerminators, _isBasicASCII, _normalizeEOL) {
10
+ this._chunks = _chunks;
11
+ this._bom = _bom;
12
+ this._cr = _cr;
13
+ this._lf = _lf;
14
+ this._crlf = _crlf;
15
+ this._containsRTL = _containsRTL;
16
+ this._containsUnusualLineTerminators = _containsUnusualLineTerminators;
17
+ this._isBasicASCII = _isBasicASCII;
18
+ this._normalizeEOL = _normalizeEOL;
19
+ }
20
+ _getEOL(defaultEOL) {
21
+ const totalEOLCount = this._cr + this._lf + this._crlf;
22
+ const totalCRCount = this._cr + this._crlf;
23
+ if (totalEOLCount === 0) {
24
+ // This is an empty file or a file with precisely one line
25
+ return (defaultEOL === 1 /* DefaultEndOfLine.LF */ ? '\n' : '\r\n');
26
+ }
27
+ if (totalCRCount > totalEOLCount / 2) {
28
+ // More than half of the file contains \r\n ending lines
29
+ return '\r\n';
30
+ }
31
+ // At least one line more ends in \n
32
+ return '\n';
33
+ }
34
+ create(defaultEOL) {
35
+ const eol = this._getEOL(defaultEOL);
36
+ const chunks = this._chunks;
37
+ if (this._normalizeEOL &&
38
+ ((eol === '\r\n' && (this._cr > 0 || this._lf > 0))
39
+ || (eol === '\n' && (this._cr > 0 || this._crlf > 0)))) {
40
+ // Normalize pieces
41
+ for (let i = 0, len = chunks.length; i < len; i++) {
42
+ const str = chunks[i].buffer.replace(/\r\n|\r|\n/g, eol);
43
+ const newLineStart = createLineStartsFast(str);
44
+ chunks[i] = new StringBuffer(str, newLineStart);
45
+ }
46
+ }
47
+ const textBuffer = new PieceTreeTextBuffer(chunks, this._bom, eol, this._containsRTL, this._containsUnusualLineTerminators, this._isBasicASCII, this._normalizeEOL);
48
+ return { textBuffer: textBuffer, disposable: textBuffer };
49
+ }
50
+ }
51
+ export class PieceTreeTextBufferBuilder {
52
+ constructor() {
53
+ this.chunks = [];
54
+ this.BOM = '';
55
+ this._hasPreviousChar = false;
56
+ this._previousChar = 0;
57
+ this._tmpLineStarts = [];
58
+ this.cr = 0;
59
+ this.lf = 0;
60
+ this.crlf = 0;
61
+ this.containsRTL = false;
62
+ this.containsUnusualLineTerminators = false;
63
+ this.isBasicASCII = true;
64
+ }
65
+ acceptChunk(chunk) {
66
+ if (chunk.length === 0) {
67
+ return;
68
+ }
69
+ if (this.chunks.length === 0) {
70
+ if (strings.startsWithUTF8BOM(chunk)) {
71
+ this.BOM = strings.UTF8_BOM_CHARACTER;
72
+ chunk = chunk.substr(1);
73
+ }
74
+ }
75
+ const lastChar = chunk.charCodeAt(chunk.length - 1);
76
+ if (lastChar === 13 /* CharCode.CarriageReturn */ || (lastChar >= 0xD800 && lastChar <= 0xDBFF)) {
77
+ // last character is \r or a high surrogate => keep it back
78
+ this._acceptChunk1(chunk.substr(0, chunk.length - 1), false);
79
+ this._hasPreviousChar = true;
80
+ this._previousChar = lastChar;
81
+ }
82
+ else {
83
+ this._acceptChunk1(chunk, false);
84
+ this._hasPreviousChar = false;
85
+ this._previousChar = lastChar;
86
+ }
87
+ }
88
+ _acceptChunk1(chunk, allowEmptyStrings) {
89
+ if (!allowEmptyStrings && chunk.length === 0) {
90
+ // Nothing to do
91
+ return;
92
+ }
93
+ if (this._hasPreviousChar) {
94
+ this._acceptChunk2(String.fromCharCode(this._previousChar) + chunk);
95
+ }
96
+ else {
97
+ this._acceptChunk2(chunk);
98
+ }
99
+ }
100
+ _acceptChunk2(chunk) {
101
+ const lineStarts = createLineStarts(this._tmpLineStarts, chunk);
102
+ this.chunks.push(new StringBuffer(chunk, lineStarts.lineStarts));
103
+ this.cr += lineStarts.cr;
104
+ this.lf += lineStarts.lf;
105
+ this.crlf += lineStarts.crlf;
106
+ if (!lineStarts.isBasicASCII) {
107
+ // this chunk contains non basic ASCII characters
108
+ this.isBasicASCII = false;
109
+ if (!this.containsRTL) {
110
+ this.containsRTL = strings.containsRTL(chunk);
111
+ }
112
+ if (!this.containsUnusualLineTerminators) {
113
+ this.containsUnusualLineTerminators = strings.containsUnusualLineTerminators(chunk);
114
+ }
115
+ }
116
+ }
117
+ finish(normalizeEOL = true) {
118
+ this._finish();
119
+ return new PieceTreeTextBufferFactory(this.chunks, this.BOM, this.cr, this.lf, this.crlf, this.containsRTL, this.containsUnusualLineTerminators, this.isBasicASCII, normalizeEOL);
120
+ }
121
+ _finish() {
122
+ if (this.chunks.length === 0) {
123
+ this._acceptChunk1('', true);
124
+ }
125
+ if (this._hasPreviousChar) {
126
+ this._hasPreviousChar = false;
127
+ // recreate last chunk
128
+ const lastChunk = this.chunks[this.chunks.length - 1];
129
+ lastChunk.buffer += String.fromCharCode(this._previousChar);
130
+ const newLineStarts = createLineStartsFast(lastChunk.buffer);
131
+ lastChunk.lineStarts = newLineStarts;
132
+ if (this._previousChar === 13 /* CharCode.CarriageReturn */) {
133
+ this.cr++;
134
+ }
135
+ }
136
+ }
137
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.js ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export class TreeNode {
6
+ constructor(piece, color) {
7
+ this.piece = piece;
8
+ this.color = color;
9
+ this.size_left = 0;
10
+ this.lf_left = 0;
11
+ this.parent = this;
12
+ this.left = this;
13
+ this.right = this;
14
+ }
15
+ next() {
16
+ if (this.right !== SENTINEL) {
17
+ return leftest(this.right);
18
+ }
19
+ let node = this;
20
+ while (node.parent !== SENTINEL) {
21
+ if (node.parent.left === node) {
22
+ break;
23
+ }
24
+ node = node.parent;
25
+ }
26
+ if (node.parent === SENTINEL) {
27
+ return SENTINEL;
28
+ }
29
+ else {
30
+ return node.parent;
31
+ }
32
+ }
33
+ prev() {
34
+ if (this.left !== SENTINEL) {
35
+ return righttest(this.left);
36
+ }
37
+ let node = this;
38
+ while (node.parent !== SENTINEL) {
39
+ if (node.parent.right === node) {
40
+ break;
41
+ }
42
+ node = node.parent;
43
+ }
44
+ if (node.parent === SENTINEL) {
45
+ return SENTINEL;
46
+ }
47
+ else {
48
+ return node.parent;
49
+ }
50
+ }
51
+ detach() {
52
+ this.parent = null;
53
+ this.left = null;
54
+ this.right = null;
55
+ }
56
+ }
57
+ export const SENTINEL = new TreeNode(null, 0 /* NodeColor.Black */);
58
+ SENTINEL.parent = SENTINEL;
59
+ SENTINEL.left = SENTINEL;
60
+ SENTINEL.right = SENTINEL;
61
+ SENTINEL.color = 0 /* NodeColor.Black */;
62
+ export function leftest(node) {
63
+ while (node.left !== SENTINEL) {
64
+ node = node.left;
65
+ }
66
+ return node;
67
+ }
68
+ export function righttest(node) {
69
+ while (node.right !== SENTINEL) {
70
+ node = node.right;
71
+ }
72
+ return node;
73
+ }
74
+ function calculateSize(node) {
75
+ if (node === SENTINEL) {
76
+ return 0;
77
+ }
78
+ return node.size_left + node.piece.length + calculateSize(node.right);
79
+ }
80
+ function calculateLF(node) {
81
+ if (node === SENTINEL) {
82
+ return 0;
83
+ }
84
+ return node.lf_left + node.piece.lineFeedCnt + calculateLF(node.right);
85
+ }
86
+ function resetSentinel() {
87
+ SENTINEL.parent = SENTINEL;
88
+ }
89
+ export function leftRotate(tree, x) {
90
+ const y = x.right;
91
+ // fix size_left
92
+ y.size_left += x.size_left + (x.piece ? x.piece.length : 0);
93
+ y.lf_left += x.lf_left + (x.piece ? x.piece.lineFeedCnt : 0);
94
+ x.right = y.left;
95
+ if (y.left !== SENTINEL) {
96
+ y.left.parent = x;
97
+ }
98
+ y.parent = x.parent;
99
+ if (x.parent === SENTINEL) {
100
+ tree.root = y;
101
+ }
102
+ else if (x.parent.left === x) {
103
+ x.parent.left = y;
104
+ }
105
+ else {
106
+ x.parent.right = y;
107
+ }
108
+ y.left = x;
109
+ x.parent = y;
110
+ }
111
+ export function rightRotate(tree, y) {
112
+ const x = y.left;
113
+ y.left = x.right;
114
+ if (x.right !== SENTINEL) {
115
+ x.right.parent = y;
116
+ }
117
+ x.parent = y.parent;
118
+ // fix size_left
119
+ y.size_left -= x.size_left + (x.piece ? x.piece.length : 0);
120
+ y.lf_left -= x.lf_left + (x.piece ? x.piece.lineFeedCnt : 0);
121
+ if (y.parent === SENTINEL) {
122
+ tree.root = x;
123
+ }
124
+ else if (y === y.parent.right) {
125
+ y.parent.right = x;
126
+ }
127
+ else {
128
+ y.parent.left = x;
129
+ }
130
+ x.right = y;
131
+ y.parent = x;
132
+ }
133
+ export function rbDelete(tree, z) {
134
+ let x;
135
+ let y;
136
+ if (z.left === SENTINEL) {
137
+ y = z;
138
+ x = y.right;
139
+ }
140
+ else if (z.right === SENTINEL) {
141
+ y = z;
142
+ x = y.left;
143
+ }
144
+ else {
145
+ y = leftest(z.right);
146
+ x = y.right;
147
+ }
148
+ if (y === tree.root) {
149
+ tree.root = x;
150
+ // if x is null, we are removing the only node
151
+ x.color = 0 /* NodeColor.Black */;
152
+ z.detach();
153
+ resetSentinel();
154
+ tree.root.parent = SENTINEL;
155
+ return;
156
+ }
157
+ const yWasRed = (y.color === 1 /* NodeColor.Red */);
158
+ if (y === y.parent.left) {
159
+ y.parent.left = x;
160
+ }
161
+ else {
162
+ y.parent.right = x;
163
+ }
164
+ if (y === z) {
165
+ x.parent = y.parent;
166
+ recomputeTreeMetadata(tree, x);
167
+ }
168
+ else {
169
+ if (y.parent === z) {
170
+ x.parent = y;
171
+ }
172
+ else {
173
+ x.parent = y.parent;
174
+ }
175
+ // as we make changes to x's hierarchy, update size_left of subtree first
176
+ recomputeTreeMetadata(tree, x);
177
+ y.left = z.left;
178
+ y.right = z.right;
179
+ y.parent = z.parent;
180
+ y.color = z.color;
181
+ if (z === tree.root) {
182
+ tree.root = y;
183
+ }
184
+ else {
185
+ if (z === z.parent.left) {
186
+ z.parent.left = y;
187
+ }
188
+ else {
189
+ z.parent.right = y;
190
+ }
191
+ }
192
+ if (y.left !== SENTINEL) {
193
+ y.left.parent = y;
194
+ }
195
+ if (y.right !== SENTINEL) {
196
+ y.right.parent = y;
197
+ }
198
+ // update metadata
199
+ // we replace z with y, so in this sub tree, the length change is z.item.length
200
+ y.size_left = z.size_left;
201
+ y.lf_left = z.lf_left;
202
+ recomputeTreeMetadata(tree, y);
203
+ }
204
+ z.detach();
205
+ if (x.parent.left === x) {
206
+ const newSizeLeft = calculateSize(x);
207
+ const newLFLeft = calculateLF(x);
208
+ if (newSizeLeft !== x.parent.size_left || newLFLeft !== x.parent.lf_left) {
209
+ const delta = newSizeLeft - x.parent.size_left;
210
+ const lf_delta = newLFLeft - x.parent.lf_left;
211
+ x.parent.size_left = newSizeLeft;
212
+ x.parent.lf_left = newLFLeft;
213
+ updateTreeMetadata(tree, x.parent, delta, lf_delta);
214
+ }
215
+ }
216
+ recomputeTreeMetadata(tree, x.parent);
217
+ if (yWasRed) {
218
+ resetSentinel();
219
+ return;
220
+ }
221
+ // RB-DELETE-FIXUP
222
+ let w;
223
+ while (x !== tree.root && x.color === 0 /* NodeColor.Black */) {
224
+ if (x === x.parent.left) {
225
+ w = x.parent.right;
226
+ if (w.color === 1 /* NodeColor.Red */) {
227
+ w.color = 0 /* NodeColor.Black */;
228
+ x.parent.color = 1 /* NodeColor.Red */;
229
+ leftRotate(tree, x.parent);
230
+ w = x.parent.right;
231
+ }
232
+ if (w.left.color === 0 /* NodeColor.Black */ && w.right.color === 0 /* NodeColor.Black */) {
233
+ w.color = 1 /* NodeColor.Red */;
234
+ x = x.parent;
235
+ }
236
+ else {
237
+ if (w.right.color === 0 /* NodeColor.Black */) {
238
+ w.left.color = 0 /* NodeColor.Black */;
239
+ w.color = 1 /* NodeColor.Red */;
240
+ rightRotate(tree, w);
241
+ w = x.parent.right;
242
+ }
243
+ w.color = x.parent.color;
244
+ x.parent.color = 0 /* NodeColor.Black */;
245
+ w.right.color = 0 /* NodeColor.Black */;
246
+ leftRotate(tree, x.parent);
247
+ x = tree.root;
248
+ }
249
+ }
250
+ else {
251
+ w = x.parent.left;
252
+ if (w.color === 1 /* NodeColor.Red */) {
253
+ w.color = 0 /* NodeColor.Black */;
254
+ x.parent.color = 1 /* NodeColor.Red */;
255
+ rightRotate(tree, x.parent);
256
+ w = x.parent.left;
257
+ }
258
+ if (w.left.color === 0 /* NodeColor.Black */ && w.right.color === 0 /* NodeColor.Black */) {
259
+ w.color = 1 /* NodeColor.Red */;
260
+ x = x.parent;
261
+ }
262
+ else {
263
+ if (w.left.color === 0 /* NodeColor.Black */) {
264
+ w.right.color = 0 /* NodeColor.Black */;
265
+ w.color = 1 /* NodeColor.Red */;
266
+ leftRotate(tree, w);
267
+ w = x.parent.left;
268
+ }
269
+ w.color = x.parent.color;
270
+ x.parent.color = 0 /* NodeColor.Black */;
271
+ w.left.color = 0 /* NodeColor.Black */;
272
+ rightRotate(tree, x.parent);
273
+ x = tree.root;
274
+ }
275
+ }
276
+ }
277
+ x.color = 0 /* NodeColor.Black */;
278
+ resetSentinel();
279
+ }
280
+ export function fixInsert(tree, x) {
281
+ recomputeTreeMetadata(tree, x);
282
+ while (x !== tree.root && x.parent.color === 1 /* NodeColor.Red */) {
283
+ if (x.parent === x.parent.parent.left) {
284
+ const y = x.parent.parent.right;
285
+ if (y.color === 1 /* NodeColor.Red */) {
286
+ x.parent.color = 0 /* NodeColor.Black */;
287
+ y.color = 0 /* NodeColor.Black */;
288
+ x.parent.parent.color = 1 /* NodeColor.Red */;
289
+ x = x.parent.parent;
290
+ }
291
+ else {
292
+ if (x === x.parent.right) {
293
+ x = x.parent;
294
+ leftRotate(tree, x);
295
+ }
296
+ x.parent.color = 0 /* NodeColor.Black */;
297
+ x.parent.parent.color = 1 /* NodeColor.Red */;
298
+ rightRotate(tree, x.parent.parent);
299
+ }
300
+ }
301
+ else {
302
+ const y = x.parent.parent.left;
303
+ if (y.color === 1 /* NodeColor.Red */) {
304
+ x.parent.color = 0 /* NodeColor.Black */;
305
+ y.color = 0 /* NodeColor.Black */;
306
+ x.parent.parent.color = 1 /* NodeColor.Red */;
307
+ x = x.parent.parent;
308
+ }
309
+ else {
310
+ if (x === x.parent.left) {
311
+ x = x.parent;
312
+ rightRotate(tree, x);
313
+ }
314
+ x.parent.color = 0 /* NodeColor.Black */;
315
+ x.parent.parent.color = 1 /* NodeColor.Red */;
316
+ leftRotate(tree, x.parent.parent);
317
+ }
318
+ }
319
+ }
320
+ tree.root.color = 0 /* NodeColor.Black */;
321
+ }
322
+ export function updateTreeMetadata(tree, x, delta, lineFeedCntDelta) {
323
+ // node length change or line feed count change
324
+ while (x !== tree.root && x !== SENTINEL) {
325
+ if (x.parent.left === x) {
326
+ x.parent.size_left += delta;
327
+ x.parent.lf_left += lineFeedCntDelta;
328
+ }
329
+ x = x.parent;
330
+ }
331
+ }
332
+ export function recomputeTreeMetadata(tree, x) {
333
+ let delta = 0;
334
+ let lf_delta = 0;
335
+ if (x === tree.root) {
336
+ return;
337
+ }
338
+ // go upwards till the node whose left subtree is changed.
339
+ while (x !== tree.root && x === x.parent.right) {
340
+ x = x.parent;
341
+ }
342
+ if (x === tree.root) {
343
+ // well, it means we add a node to the end (inorder)
344
+ return;
345
+ }
346
+ // x is the node whose right subtree is changed.
347
+ x = x.parent;
348
+ delta = calculateSize(x.left) - x.size_left;
349
+ lf_delta = calculateLF(x.left) - x.lf_left;
350
+ x.size_left += delta;
351
+ x.lf_left += lf_delta;
352
+ // go upwards till root. O(logN)
353
+ while (x !== tree.root && (delta !== 0 || lf_delta !== 0)) {
354
+ if (x.parent.left === x) {
355
+ x.parent.size_left += delta;
356
+ x.parent.lf_left += lf_delta;
357
+ }
358
+ x = x.parent;
359
+ }
360
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/prefixSumComputer.js ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { arrayInsert } from '../../../base/common/arrays.js';
6
+ import { toUint32 } from '../../../base/common/uint.js';
7
+ export class PrefixSumComputer {
8
+ constructor(values) {
9
+ this.values = values;
10
+ this.prefixSum = new Uint32Array(values.length);
11
+ this.prefixSumValidIndex = new Int32Array(1);
12
+ this.prefixSumValidIndex[0] = -1;
13
+ }
14
+ insertValues(insertIndex, insertValues) {
15
+ insertIndex = toUint32(insertIndex);
16
+ const oldValues = this.values;
17
+ const oldPrefixSum = this.prefixSum;
18
+ const insertValuesLen = insertValues.length;
19
+ if (insertValuesLen === 0) {
20
+ return false;
21
+ }
22
+ this.values = new Uint32Array(oldValues.length + insertValuesLen);
23
+ this.values.set(oldValues.subarray(0, insertIndex), 0);
24
+ this.values.set(oldValues.subarray(insertIndex), insertIndex + insertValuesLen);
25
+ this.values.set(insertValues, insertIndex);
26
+ if (insertIndex - 1 < this.prefixSumValidIndex[0]) {
27
+ this.prefixSumValidIndex[0] = insertIndex - 1;
28
+ }
29
+ this.prefixSum = new Uint32Array(this.values.length);
30
+ if (this.prefixSumValidIndex[0] >= 0) {
31
+ this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));
32
+ }
33
+ return true;
34
+ }
35
+ setValue(index, value) {
36
+ index = toUint32(index);
37
+ value = toUint32(value);
38
+ if (this.values[index] === value) {
39
+ return false;
40
+ }
41
+ this.values[index] = value;
42
+ if (index - 1 < this.prefixSumValidIndex[0]) {
43
+ this.prefixSumValidIndex[0] = index - 1;
44
+ }
45
+ return true;
46
+ }
47
+ removeValues(startIndex, count) {
48
+ startIndex = toUint32(startIndex);
49
+ count = toUint32(count);
50
+ const oldValues = this.values;
51
+ const oldPrefixSum = this.prefixSum;
52
+ if (startIndex >= oldValues.length) {
53
+ return false;
54
+ }
55
+ const maxCount = oldValues.length - startIndex;
56
+ if (count >= maxCount) {
57
+ count = maxCount;
58
+ }
59
+ if (count === 0) {
60
+ return false;
61
+ }
62
+ this.values = new Uint32Array(oldValues.length - count);
63
+ this.values.set(oldValues.subarray(0, startIndex), 0);
64
+ this.values.set(oldValues.subarray(startIndex + count), startIndex);
65
+ this.prefixSum = new Uint32Array(this.values.length);
66
+ if (startIndex - 1 < this.prefixSumValidIndex[0]) {
67
+ this.prefixSumValidIndex[0] = startIndex - 1;
68
+ }
69
+ if (this.prefixSumValidIndex[0] >= 0) {
70
+ this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));
71
+ }
72
+ return true;
73
+ }
74
+ getTotalSum() {
75
+ if (this.values.length === 0) {
76
+ return 0;
77
+ }
78
+ return this._getPrefixSum(this.values.length - 1);
79
+ }
80
+ /**
81
+ * Returns the sum of the first `index + 1` many items.
82
+ * @returns `SUM(0 <= j <= index, values[j])`.
83
+ */
84
+ getPrefixSum(index) {
85
+ if (index < 0) {
86
+ return 0;
87
+ }
88
+ index = toUint32(index);
89
+ return this._getPrefixSum(index);
90
+ }
91
+ _getPrefixSum(index) {
92
+ if (index <= this.prefixSumValidIndex[0]) {
93
+ return this.prefixSum[index];
94
+ }
95
+ let startIndex = this.prefixSumValidIndex[0] + 1;
96
+ if (startIndex === 0) {
97
+ this.prefixSum[0] = this.values[0];
98
+ startIndex++;
99
+ }
100
+ if (index >= this.values.length) {
101
+ index = this.values.length - 1;
102
+ }
103
+ for (let i = startIndex; i <= index; i++) {
104
+ this.prefixSum[i] = this.prefixSum[i - 1] + this.values[i];
105
+ }
106
+ this.prefixSumValidIndex[0] = Math.max(this.prefixSumValidIndex[0], index);
107
+ return this.prefixSum[index];
108
+ }
109
+ getIndexOf(sum) {
110
+ sum = Math.floor(sum);
111
+ // Compute all sums (to get a fully valid prefixSum)
112
+ this.getTotalSum();
113
+ let low = 0;
114
+ let high = this.values.length - 1;
115
+ let mid = 0;
116
+ let midStop = 0;
117
+ let midStart = 0;
118
+ while (low <= high) {
119
+ mid = low + ((high - low) / 2) | 0;
120
+ midStop = this.prefixSum[mid];
121
+ midStart = midStop - this.values[mid];
122
+ if (sum < midStart) {
123
+ high = mid - 1;
124
+ }
125
+ else if (sum >= midStop) {
126
+ low = mid + 1;
127
+ }
128
+ else {
129
+ break;
130
+ }
131
+ }
132
+ return new PrefixSumIndexOfResult(mid, sum - midStart);
133
+ }
134
+ }
135
+ /**
136
+ * {@link getIndexOf} has an amortized runtime complexity of O(1).
137
+ *
138
+ * ({@link PrefixSumComputer.getIndexOf} is just O(log n))
139
+ */
140
+ export class ConstantTimePrefixSumComputer {
141
+ constructor(values) {
142
+ this._values = values;
143
+ this._isValid = false;
144
+ this._validEndIndex = -1;
145
+ this._prefixSum = [];
146
+ this._indexBySum = [];
147
+ }
148
+ /**
149
+ * @returns SUM(0 <= j < values.length, values[j])
150
+ */
151
+ getTotalSum() {
152
+ this._ensureValid();
153
+ return this._indexBySum.length;
154
+ }
155
+ /**
156
+ * Returns the sum of the first `count` many items.
157
+ * @returns `SUM(0 <= j < count, values[j])`.
158
+ */
159
+ getPrefixSum(count) {
160
+ this._ensureValid();
161
+ if (count === 0) {
162
+ return 0;
163
+ }
164
+ return this._prefixSum[count - 1];
165
+ }
166
+ /**
167
+ * @returns `result`, such that `getPrefixSum(result.index) + result.remainder = sum`
168
+ */
169
+ getIndexOf(sum) {
170
+ this._ensureValid();
171
+ const idx = this._indexBySum[sum];
172
+ const viewLinesAbove = idx > 0 ? this._prefixSum[idx - 1] : 0;
173
+ return new PrefixSumIndexOfResult(idx, sum - viewLinesAbove);
174
+ }
175
+ removeValues(start, deleteCount) {
176
+ this._values.splice(start, deleteCount);
177
+ this._invalidate(start);
178
+ }
179
+ insertValues(insertIndex, insertArr) {
180
+ this._values = arrayInsert(this._values, insertIndex, insertArr);
181
+ this._invalidate(insertIndex);
182
+ }
183
+ _invalidate(index) {
184
+ this._isValid = false;
185
+ this._validEndIndex = Math.min(this._validEndIndex, index - 1);
186
+ }
187
+ _ensureValid() {
188
+ if (this._isValid) {
189
+ return;
190
+ }
191
+ for (let i = this._validEndIndex + 1, len = this._values.length; i < len; i++) {
192
+ const value = this._values[i];
193
+ const sumAbove = i > 0 ? this._prefixSum[i - 1] : 0;
194
+ this._prefixSum[i] = sumAbove + value;
195
+ for (let j = 0; j < value; j++) {
196
+ this._indexBySum[sumAbove + j] = i;
197
+ }
198
+ }
199
+ // trim things
200
+ this._prefixSum.length = this._values.length;
201
+ this._indexBySum.length = this._prefixSum[this._prefixSum.length - 1];
202
+ // mark as valid
203
+ this._isValid = true;
204
+ this._validEndIndex = this._values.length - 1;
205
+ }
206
+ setValue(index, value) {
207
+ if (this._values[index] === value) {
208
+ // no change
209
+ return;
210
+ }
211
+ this._values[index] = value;
212
+ this._invalidate(index);
213
+ }
214
+ }
215
+ export class PrefixSumIndexOfResult {
216
+ constructor(index, remainder) {
217
+ this.index = index;
218
+ this.remainder = remainder;
219
+ this._prefixSumIndexOfResultBrand = undefined;
220
+ this.index = index;
221
+ this.remainder = remainder;
222
+ }
223
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/textModel.js ADDED
@@ -0,0 +1,1899 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
6
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
8
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var TextModel_1;
15
+ import { ArrayQueue, pushMany } from '../../../base/common/arrays.js';
16
+ import { Color } from '../../../base/common/color.js';
17
+ import { BugIndicatingError, illegalArgument, onUnexpectedError } from '../../../base/common/errors.js';
18
+ import { Emitter } from '../../../base/common/event.js';
19
+ import { Disposable, MutableDisposable, combinedDisposable } from '../../../base/common/lifecycle.js';
20
+ import * as strings from '../../../base/common/strings.js';
21
+ import { URI } from '../../../base/common/uri.js';
22
+ import { countEOL } from '../core/eolCounter.js';
23
+ import { normalizeIndentation } from '../core/indentation.js';
24
+ import { Position } from '../core/position.js';
25
+ import { Range } from '../core/range.js';
26
+ import { Selection } from '../core/selection.js';
27
+ import { EDITOR_MODEL_DEFAULTS } from '../core/textModelDefaults.js';
28
+ import { ILanguageService } from '../languages/language.js';
29
+ import { ILanguageConfigurationService } from '../languages/languageConfigurationRegistry.js';
30
+ import * as model from '../model.js';
31
+ import { BracketPairsTextModelPart } from './bracketPairsTextModelPart/bracketPairsImpl.js';
32
+ import { ColorizedBracketPairsDecorationProvider } from './bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.js';
33
+ import { EditStack } from './editStack.js';
34
+ import { GuidesTextModelPart } from './guidesTextModelPart.js';
35
+ import { guessIndentation } from './indentationGuesser.js';
36
+ import { IntervalNode, IntervalTree, recomputeMaxEnd } from './intervalTree.js';
37
+ import { PieceTreeTextBuffer } from './pieceTreeTextBuffer/pieceTreeTextBuffer.js';
38
+ import { PieceTreeTextBufferBuilder } from './pieceTreeTextBuffer/pieceTreeTextBufferBuilder.js';
39
+ import { SearchParams, TextModelSearch } from './textModelSearch.js';
40
+ import { TokenizationTextModelPart } from './tokenizationTextModelPart.js';
41
+ import { AttachedViews } from './tokens.js';
42
+ import { InternalModelContentChangeEvent, LineInjectedText, ModelInjectedTextChangedEvent, ModelRawContentChangedEvent, ModelRawEOLChanged, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from '../textModelEvents.js';
43
+ import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js';
44
+ import { IUndoRedoService } from '../../../platform/undoRedo/common/undoRedo.js';
45
+ export function createTextBufferFactory(text) {
46
+ const builder = new PieceTreeTextBufferBuilder();
47
+ builder.acceptChunk(text);
48
+ return builder.finish();
49
+ }
50
+ export function createTextBufferFactoryFromSnapshot(snapshot) {
51
+ const builder = new PieceTreeTextBufferBuilder();
52
+ let chunk;
53
+ while (typeof (chunk = snapshot.read()) === 'string') {
54
+ builder.acceptChunk(chunk);
55
+ }
56
+ return builder.finish();
57
+ }
58
+ export function createTextBuffer(value, defaultEOL) {
59
+ let factory;
60
+ if (typeof value === 'string') {
61
+ factory = createTextBufferFactory(value);
62
+ }
63
+ else if (model.isITextSnapshot(value)) {
64
+ factory = createTextBufferFactoryFromSnapshot(value);
65
+ }
66
+ else {
67
+ factory = value;
68
+ }
69
+ return factory.create(defaultEOL);
70
+ }
71
+ let MODEL_ID = 0;
72
+ const LIMIT_FIND_COUNT = 999;
73
+ const LONG_LINE_BOUNDARY = 10000;
74
+ class TextModelSnapshot {
75
+ constructor(source) {
76
+ this._source = source;
77
+ this._eos = false;
78
+ }
79
+ read() {
80
+ if (this._eos) {
81
+ return null;
82
+ }
83
+ const result = [];
84
+ let resultCnt = 0;
85
+ let resultLength = 0;
86
+ do {
87
+ const tmp = this._source.read();
88
+ if (tmp === null) {
89
+ // end-of-stream
90
+ this._eos = true;
91
+ if (resultCnt === 0) {
92
+ return null;
93
+ }
94
+ else {
95
+ return result.join('');
96
+ }
97
+ }
98
+ if (tmp.length > 0) {
99
+ result[resultCnt++] = tmp;
100
+ resultLength += tmp.length;
101
+ }
102
+ if (resultLength >= 64 * 1024) {
103
+ return result.join('');
104
+ }
105
+ } while (true);
106
+ }
107
+ }
108
+ const invalidFunc = () => { throw new Error(`Invalid change accessor`); };
109
+ let TextModel = class TextModel extends Disposable {
110
+ static { TextModel_1 = this; }
111
+ static { this._MODEL_SYNC_LIMIT = 50 * 1024 * 1024; } // 50 MB, // used in tests
112
+ static { this.LARGE_FILE_SIZE_THRESHOLD = 20 * 1024 * 1024; } // 20 MB;
113
+ static { this.LARGE_FILE_LINE_COUNT_THRESHOLD = 300 * 1000; } // 300K lines
114
+ static { this.LARGE_FILE_HEAP_OPERATION_THRESHOLD = 256 * 1024 * 1024; } // 256M characters, usually ~> 512MB memory usage
115
+ static { this.DEFAULT_CREATION_OPTIONS = {
116
+ isForSimpleWidget: false,
117
+ tabSize: EDITOR_MODEL_DEFAULTS.tabSize,
118
+ indentSize: EDITOR_MODEL_DEFAULTS.indentSize,
119
+ insertSpaces: EDITOR_MODEL_DEFAULTS.insertSpaces,
120
+ detectIndentation: false,
121
+ defaultEOL: 1 /* model.DefaultEndOfLine.LF */,
122
+ trimAutoWhitespace: EDITOR_MODEL_DEFAULTS.trimAutoWhitespace,
123
+ largeFileOptimizations: EDITOR_MODEL_DEFAULTS.largeFileOptimizations,
124
+ bracketPairColorizationOptions: EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions,
125
+ }; }
126
+ static resolveOptions(textBuffer, options) {
127
+ if (options.detectIndentation) {
128
+ const guessedIndentation = guessIndentation(textBuffer, options.tabSize, options.insertSpaces);
129
+ return new model.TextModelResolvedOptions({
130
+ tabSize: guessedIndentation.tabSize,
131
+ indentSize: 'tabSize', // TODO@Alex: guess indentSize independent of tabSize
132
+ insertSpaces: guessedIndentation.insertSpaces,
133
+ trimAutoWhitespace: options.trimAutoWhitespace,
134
+ defaultEOL: options.defaultEOL,
135
+ bracketPairColorizationOptions: options.bracketPairColorizationOptions,
136
+ });
137
+ }
138
+ return new model.TextModelResolvedOptions(options);
139
+ }
140
+ get onDidChangeLanguage() { return this._tokenizationTextModelPart.onDidChangeLanguage; }
141
+ get onDidChangeLanguageConfiguration() { return this._tokenizationTextModelPart.onDidChangeLanguageConfiguration; }
142
+ get onDidChangeTokens() { return this._tokenizationTextModelPart.onDidChangeTokens; }
143
+ onDidChangeContent(listener) {
144
+ return this._eventEmitter.slowEvent((e) => listener(e.contentChangedEvent));
145
+ }
146
+ onDidChangeContentOrInjectedText(listener) {
147
+ return combinedDisposable(this._eventEmitter.fastEvent(e => listener(e)), this._onDidChangeInjectedText.event(e => listener(e)));
148
+ }
149
+ _isDisposing() { return this.__isDisposing; }
150
+ get tokenization() { return this._tokenizationTextModelPart; }
151
+ get bracketPairs() { return this._bracketPairs; }
152
+ get guides() { return this._guidesTextModelPart; }
153
+ constructor(source, languageIdOrSelection, creationOptions, associatedResource = null, _undoRedoService, _languageService, _languageConfigurationService, instantiationService) {
154
+ super();
155
+ this._undoRedoService = _undoRedoService;
156
+ this._languageService = _languageService;
157
+ this._languageConfigurationService = _languageConfigurationService;
158
+ this.instantiationService = instantiationService;
159
+ //#region Events
160
+ this._onWillDispose = this._register(new Emitter());
161
+ this.onWillDispose = this._onWillDispose.event;
162
+ this._onDidChangeDecorations = this._register(new DidChangeDecorationsEmitter(affectedInjectedTextLines => this.handleBeforeFireDecorationsChangedEvent(affectedInjectedTextLines)));
163
+ this.onDidChangeDecorations = this._onDidChangeDecorations.event;
164
+ this._onDidChangeOptions = this._register(new Emitter());
165
+ this.onDidChangeOptions = this._onDidChangeOptions.event;
166
+ this._onDidChangeAttached = this._register(new Emitter());
167
+ this.onDidChangeAttached = this._onDidChangeAttached.event;
168
+ this._onDidChangeInjectedText = this._register(new Emitter());
169
+ this._eventEmitter = this._register(new DidChangeContentEmitter());
170
+ this._languageSelectionListener = this._register(new MutableDisposable());
171
+ this._deltaDecorationCallCnt = 0;
172
+ this._attachedViews = new AttachedViews();
173
+ // Generate a new unique model id
174
+ MODEL_ID++;
175
+ this.id = '$model' + MODEL_ID;
176
+ this.isForSimpleWidget = creationOptions.isForSimpleWidget;
177
+ if (typeof associatedResource === 'undefined' || associatedResource === null) {
178
+ this._associatedResource = URI.parse('inmemory://model/' + MODEL_ID);
179
+ }
180
+ else {
181
+ this._associatedResource = associatedResource;
182
+ }
183
+ this._attachedEditorCount = 0;
184
+ const { textBuffer, disposable } = createTextBuffer(source, creationOptions.defaultEOL);
185
+ this._buffer = textBuffer;
186
+ this._bufferDisposable = disposable;
187
+ this._options = TextModel_1.resolveOptions(this._buffer, creationOptions);
188
+ const languageId = (typeof languageIdOrSelection === 'string' ? languageIdOrSelection : languageIdOrSelection.languageId);
189
+ if (typeof languageIdOrSelection !== 'string') {
190
+ this._languageSelectionListener.value = languageIdOrSelection.onDidChange(() => this._setLanguage(languageIdOrSelection.languageId));
191
+ }
192
+ this._bracketPairs = this._register(new BracketPairsTextModelPart(this, this._languageConfigurationService));
193
+ this._guidesTextModelPart = this._register(new GuidesTextModelPart(this, this._languageConfigurationService));
194
+ this._decorationProvider = this._register(new ColorizedBracketPairsDecorationProvider(this));
195
+ this._tokenizationTextModelPart = this.instantiationService.createInstance(TokenizationTextModelPart, this, this._bracketPairs, languageId, this._attachedViews);
196
+ const bufferLineCount = this._buffer.getLineCount();
197
+ const bufferTextLength = this._buffer.getValueLengthInRange(new Range(1, 1, bufferLineCount, this._buffer.getLineLength(bufferLineCount) + 1), 0 /* model.EndOfLinePreference.TextDefined */);
198
+ // !!! Make a decision in the ctor and permanently respect this decision !!!
199
+ // If a model is too large at construction time, it will never get tokenized,
200
+ // under no circumstances.
201
+ if (creationOptions.largeFileOptimizations) {
202
+ this._isTooLargeForTokenization = ((bufferTextLength > TextModel_1.LARGE_FILE_SIZE_THRESHOLD)
203
+ || (bufferLineCount > TextModel_1.LARGE_FILE_LINE_COUNT_THRESHOLD));
204
+ this._isTooLargeForHeapOperation = bufferTextLength > TextModel_1.LARGE_FILE_HEAP_OPERATION_THRESHOLD;
205
+ }
206
+ else {
207
+ this._isTooLargeForTokenization = false;
208
+ this._isTooLargeForHeapOperation = false;
209
+ }
210
+ this._isTooLargeForSyncing = (bufferTextLength > TextModel_1._MODEL_SYNC_LIMIT);
211
+ this._versionId = 1;
212
+ this._alternativeVersionId = 1;
213
+ this._initialUndoRedoSnapshot = null;
214
+ this._isDisposed = false;
215
+ this.__isDisposing = false;
216
+ this._instanceId = strings.singleLetterHash(MODEL_ID);
217
+ this._lastDecorationId = 0;
218
+ this._decorations = Object.create(null);
219
+ this._decorationsTree = new DecorationsTrees();
220
+ this._commandManager = new EditStack(this, this._undoRedoService);
221
+ this._isUndoing = false;
222
+ this._isRedoing = false;
223
+ this._trimAutoWhitespaceLines = null;
224
+ this._register(this._decorationProvider.onDidChange(() => {
225
+ this._onDidChangeDecorations.beginDeferredEmit();
226
+ this._onDidChangeDecorations.fire();
227
+ this._onDidChangeDecorations.endDeferredEmit();
228
+ }));
229
+ this._languageService.requestRichLanguageFeatures(languageId);
230
+ this._register(this._languageConfigurationService.onDidChange(e => {
231
+ this._bracketPairs.handleLanguageConfigurationServiceChange(e);
232
+ this._tokenizationTextModelPart.handleLanguageConfigurationServiceChange(e);
233
+ }));
234
+ }
235
+ dispose() {
236
+ this.__isDisposing = true;
237
+ this._onWillDispose.fire();
238
+ this._tokenizationTextModelPart.dispose();
239
+ this._isDisposed = true;
240
+ super.dispose();
241
+ this._bufferDisposable.dispose();
242
+ this.__isDisposing = false;
243
+ // Manually release reference to previous text buffer to avoid large leaks
244
+ // in case someone leaks a TextModel reference
245
+ const emptyDisposedTextBuffer = new PieceTreeTextBuffer([], '', '\n', false, false, true, true);
246
+ emptyDisposedTextBuffer.dispose();
247
+ this._buffer = emptyDisposedTextBuffer;
248
+ this._bufferDisposable = Disposable.None;
249
+ }
250
+ _assertNotDisposed() {
251
+ if (this._isDisposed) {
252
+ throw new BugIndicatingError('Model is disposed!');
253
+ }
254
+ }
255
+ _emitContentChangedEvent(rawChange, change) {
256
+ if (this.__isDisposing) {
257
+ // Do not confuse listeners by emitting any event after disposing
258
+ return;
259
+ }
260
+ this._tokenizationTextModelPart.handleDidChangeContent(change);
261
+ this._bracketPairs.handleDidChangeContent(change);
262
+ this._eventEmitter.fire(new InternalModelContentChangeEvent(rawChange, change));
263
+ }
264
+ setValue(value) {
265
+ this._assertNotDisposed();
266
+ if (value === null || value === undefined) {
267
+ throw illegalArgument();
268
+ }
269
+ const { textBuffer, disposable } = createTextBuffer(value, this._options.defaultEOL);
270
+ this._setValueFromTextBuffer(textBuffer, disposable);
271
+ }
272
+ _createContentChanged2(range, rangeOffset, rangeLength, text, isUndoing, isRedoing, isFlush, isEolChange) {
273
+ return {
274
+ changes: [{
275
+ range: range,
276
+ rangeOffset: rangeOffset,
277
+ rangeLength: rangeLength,
278
+ text: text,
279
+ }],
280
+ eol: this._buffer.getEOL(),
281
+ isEolChange: isEolChange,
282
+ versionId: this.getVersionId(),
283
+ isUndoing: isUndoing,
284
+ isRedoing: isRedoing,
285
+ isFlush: isFlush
286
+ };
287
+ }
288
+ _setValueFromTextBuffer(textBuffer, textBufferDisposable) {
289
+ this._assertNotDisposed();
290
+ const oldFullModelRange = this.getFullModelRange();
291
+ const oldModelValueLength = this.getValueLengthInRange(oldFullModelRange);
292
+ const endLineNumber = this.getLineCount();
293
+ const endColumn = this.getLineMaxColumn(endLineNumber);
294
+ this._buffer = textBuffer;
295
+ this._bufferDisposable.dispose();
296
+ this._bufferDisposable = textBufferDisposable;
297
+ this._increaseVersionId();
298
+ // Destroy all my decorations
299
+ this._decorations = Object.create(null);
300
+ this._decorationsTree = new DecorationsTrees();
301
+ // Destroy my edit history and settings
302
+ this._commandManager.clear();
303
+ this._trimAutoWhitespaceLines = null;
304
+ this._emitContentChangedEvent(new ModelRawContentChangedEvent([
305
+ new ModelRawFlush()
306
+ ], this._versionId, false, false), this._createContentChanged2(new Range(1, 1, endLineNumber, endColumn), 0, oldModelValueLength, this.getValue(), false, false, true, false));
307
+ }
308
+ setEOL(eol) {
309
+ this._assertNotDisposed();
310
+ const newEOL = (eol === 1 /* model.EndOfLineSequence.CRLF */ ? '\r\n' : '\n');
311
+ if (this._buffer.getEOL() === newEOL) {
312
+ // Nothing to do
313
+ return;
314
+ }
315
+ const oldFullModelRange = this.getFullModelRange();
316
+ const oldModelValueLength = this.getValueLengthInRange(oldFullModelRange);
317
+ const endLineNumber = this.getLineCount();
318
+ const endColumn = this.getLineMaxColumn(endLineNumber);
319
+ this._onBeforeEOLChange();
320
+ this._buffer.setEOL(newEOL);
321
+ this._increaseVersionId();
322
+ this._onAfterEOLChange();
323
+ this._emitContentChangedEvent(new ModelRawContentChangedEvent([
324
+ new ModelRawEOLChanged()
325
+ ], this._versionId, false, false), this._createContentChanged2(new Range(1, 1, endLineNumber, endColumn), 0, oldModelValueLength, this.getValue(), false, false, false, true));
326
+ }
327
+ _onBeforeEOLChange() {
328
+ // Ensure all decorations get their `range` set.
329
+ this._decorationsTree.ensureAllNodesHaveRanges(this);
330
+ }
331
+ _onAfterEOLChange() {
332
+ // Transform back `range` to offsets
333
+ const versionId = this.getVersionId();
334
+ const allDecorations = this._decorationsTree.collectNodesPostOrder();
335
+ for (let i = 0, len = allDecorations.length; i < len; i++) {
336
+ const node = allDecorations[i];
337
+ const range = node.range; // the range is defined due to `_onBeforeEOLChange`
338
+ const delta = node.cachedAbsoluteStart - node.start;
339
+ const startOffset = this._buffer.getOffsetAt(range.startLineNumber, range.startColumn);
340
+ const endOffset = this._buffer.getOffsetAt(range.endLineNumber, range.endColumn);
341
+ node.cachedAbsoluteStart = startOffset;
342
+ node.cachedAbsoluteEnd = endOffset;
343
+ node.cachedVersionId = versionId;
344
+ node.start = startOffset - delta;
345
+ node.end = endOffset - delta;
346
+ recomputeMaxEnd(node);
347
+ }
348
+ }
349
+ onBeforeAttached() {
350
+ this._attachedEditorCount++;
351
+ if (this._attachedEditorCount === 1) {
352
+ this._tokenizationTextModelPart.handleDidChangeAttached();
353
+ this._onDidChangeAttached.fire(undefined);
354
+ }
355
+ return this._attachedViews.attachView();
356
+ }
357
+ onBeforeDetached(view) {
358
+ this._attachedEditorCount--;
359
+ if (this._attachedEditorCount === 0) {
360
+ this._tokenizationTextModelPart.handleDidChangeAttached();
361
+ this._onDidChangeAttached.fire(undefined);
362
+ }
363
+ this._attachedViews.detachView(view);
364
+ }
365
+ isAttachedToEditor() {
366
+ return this._attachedEditorCount > 0;
367
+ }
368
+ getAttachedEditorCount() {
369
+ return this._attachedEditorCount;
370
+ }
371
+ isTooLargeForSyncing() {
372
+ return this._isTooLargeForSyncing;
373
+ }
374
+ isTooLargeForTokenization() {
375
+ return this._isTooLargeForTokenization;
376
+ }
377
+ isTooLargeForHeapOperation() {
378
+ return this._isTooLargeForHeapOperation;
379
+ }
380
+ isDisposed() {
381
+ return this._isDisposed;
382
+ }
383
+ isDominatedByLongLines() {
384
+ this._assertNotDisposed();
385
+ if (this.isTooLargeForTokenization()) {
386
+ // Cannot word wrap huge files anyways, so it doesn't really matter
387
+ return false;
388
+ }
389
+ let smallLineCharCount = 0;
390
+ let longLineCharCount = 0;
391
+ const lineCount = this._buffer.getLineCount();
392
+ for (let lineNumber = 1; lineNumber <= lineCount; lineNumber++) {
393
+ const lineLength = this._buffer.getLineLength(lineNumber);
394
+ if (lineLength >= LONG_LINE_BOUNDARY) {
395
+ longLineCharCount += lineLength;
396
+ }
397
+ else {
398
+ smallLineCharCount += lineLength;
399
+ }
400
+ }
401
+ return (longLineCharCount > smallLineCharCount);
402
+ }
403
+ get uri() {
404
+ return this._associatedResource;
405
+ }
406
+ //#region Options
407
+ getOptions() {
408
+ this._assertNotDisposed();
409
+ return this._options;
410
+ }
411
+ getFormattingOptions() {
412
+ return {
413
+ tabSize: this._options.indentSize,
414
+ insertSpaces: this._options.insertSpaces
415
+ };
416
+ }
417
+ updateOptions(_newOpts) {
418
+ this._assertNotDisposed();
419
+ const tabSize = (typeof _newOpts.tabSize !== 'undefined') ? _newOpts.tabSize : this._options.tabSize;
420
+ const indentSize = (typeof _newOpts.indentSize !== 'undefined') ? _newOpts.indentSize : this._options.originalIndentSize;
421
+ const insertSpaces = (typeof _newOpts.insertSpaces !== 'undefined') ? _newOpts.insertSpaces : this._options.insertSpaces;
422
+ const trimAutoWhitespace = (typeof _newOpts.trimAutoWhitespace !== 'undefined') ? _newOpts.trimAutoWhitespace : this._options.trimAutoWhitespace;
423
+ const bracketPairColorizationOptions = (typeof _newOpts.bracketColorizationOptions !== 'undefined') ? _newOpts.bracketColorizationOptions : this._options.bracketPairColorizationOptions;
424
+ const newOpts = new model.TextModelResolvedOptions({
425
+ tabSize: tabSize,
426
+ indentSize: indentSize,
427
+ insertSpaces: insertSpaces,
428
+ defaultEOL: this._options.defaultEOL,
429
+ trimAutoWhitespace: trimAutoWhitespace,
430
+ bracketPairColorizationOptions,
431
+ });
432
+ if (this._options.equals(newOpts)) {
433
+ return;
434
+ }
435
+ const e = this._options.createChangeEvent(newOpts);
436
+ this._options = newOpts;
437
+ this._bracketPairs.handleDidChangeOptions(e);
438
+ this._decorationProvider.handleDidChangeOptions(e);
439
+ this._onDidChangeOptions.fire(e);
440
+ }
441
+ detectIndentation(defaultInsertSpaces, defaultTabSize) {
442
+ this._assertNotDisposed();
443
+ const guessedIndentation = guessIndentation(this._buffer, defaultTabSize, defaultInsertSpaces);
444
+ this.updateOptions({
445
+ insertSpaces: guessedIndentation.insertSpaces,
446
+ tabSize: guessedIndentation.tabSize,
447
+ indentSize: guessedIndentation.tabSize, // TODO@Alex: guess indentSize independent of tabSize
448
+ });
449
+ }
450
+ normalizeIndentation(str) {
451
+ this._assertNotDisposed();
452
+ return normalizeIndentation(str, this._options.indentSize, this._options.insertSpaces);
453
+ }
454
+ //#endregion
455
+ //#region Reading
456
+ getVersionId() {
457
+ this._assertNotDisposed();
458
+ return this._versionId;
459
+ }
460
+ mightContainRTL() {
461
+ return this._buffer.mightContainRTL();
462
+ }
463
+ mightContainUnusualLineTerminators() {
464
+ return this._buffer.mightContainUnusualLineTerminators();
465
+ }
466
+ removeUnusualLineTerminators(selections = null) {
467
+ const matches = this.findMatches(strings.UNUSUAL_LINE_TERMINATORS.source, false, true, false, null, false, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */);
468
+ this._buffer.resetMightContainUnusualLineTerminators();
469
+ this.pushEditOperations(selections, matches.map(m => ({ range: m.range, text: null })), () => null);
470
+ }
471
+ mightContainNonBasicASCII() {
472
+ return this._buffer.mightContainNonBasicASCII();
473
+ }
474
+ getAlternativeVersionId() {
475
+ this._assertNotDisposed();
476
+ return this._alternativeVersionId;
477
+ }
478
+ getInitialUndoRedoSnapshot() {
479
+ this._assertNotDisposed();
480
+ return this._initialUndoRedoSnapshot;
481
+ }
482
+ getOffsetAt(rawPosition) {
483
+ this._assertNotDisposed();
484
+ const position = this._validatePosition(rawPosition.lineNumber, rawPosition.column, 0 /* StringOffsetValidationType.Relaxed */);
485
+ return this._buffer.getOffsetAt(position.lineNumber, position.column);
486
+ }
487
+ getPositionAt(rawOffset) {
488
+ this._assertNotDisposed();
489
+ const offset = (Math.min(this._buffer.getLength(), Math.max(0, rawOffset)));
490
+ return this._buffer.getPositionAt(offset);
491
+ }
492
+ _increaseVersionId() {
493
+ this._versionId = this._versionId + 1;
494
+ this._alternativeVersionId = this._versionId;
495
+ }
496
+ _overwriteVersionId(versionId) {
497
+ this._versionId = versionId;
498
+ }
499
+ _overwriteAlternativeVersionId(newAlternativeVersionId) {
500
+ this._alternativeVersionId = newAlternativeVersionId;
501
+ }
502
+ _overwriteInitialUndoRedoSnapshot(newInitialUndoRedoSnapshot) {
503
+ this._initialUndoRedoSnapshot = newInitialUndoRedoSnapshot;
504
+ }
505
+ getValue(eol, preserveBOM = false) {
506
+ this._assertNotDisposed();
507
+ if (this.isTooLargeForHeapOperation()) {
508
+ throw new BugIndicatingError('Operation would exceed heap memory limits');
509
+ }
510
+ const fullModelRange = this.getFullModelRange();
511
+ const fullModelValue = this.getValueInRange(fullModelRange, eol);
512
+ if (preserveBOM) {
513
+ return this._buffer.getBOM() + fullModelValue;
514
+ }
515
+ return fullModelValue;
516
+ }
517
+ createSnapshot(preserveBOM = false) {
518
+ return new TextModelSnapshot(this._buffer.createSnapshot(preserveBOM));
519
+ }
520
+ getValueLength(eol, preserveBOM = false) {
521
+ this._assertNotDisposed();
522
+ const fullModelRange = this.getFullModelRange();
523
+ const fullModelValue = this.getValueLengthInRange(fullModelRange, eol);
524
+ if (preserveBOM) {
525
+ return this._buffer.getBOM().length + fullModelValue;
526
+ }
527
+ return fullModelValue;
528
+ }
529
+ getValueInRange(rawRange, eol = 0 /* model.EndOfLinePreference.TextDefined */) {
530
+ this._assertNotDisposed();
531
+ return this._buffer.getValueInRange(this.validateRange(rawRange), eol);
532
+ }
533
+ getValueLengthInRange(rawRange, eol = 0 /* model.EndOfLinePreference.TextDefined */) {
534
+ this._assertNotDisposed();
535
+ return this._buffer.getValueLengthInRange(this.validateRange(rawRange), eol);
536
+ }
537
+ getCharacterCountInRange(rawRange, eol = 0 /* model.EndOfLinePreference.TextDefined */) {
538
+ this._assertNotDisposed();
539
+ return this._buffer.getCharacterCountInRange(this.validateRange(rawRange), eol);
540
+ }
541
+ getLineCount() {
542
+ this._assertNotDisposed();
543
+ return this._buffer.getLineCount();
544
+ }
545
+ getLineContent(lineNumber) {
546
+ this._assertNotDisposed();
547
+ if (lineNumber < 1 || lineNumber > this.getLineCount()) {
548
+ throw new BugIndicatingError('Illegal value for lineNumber');
549
+ }
550
+ return this._buffer.getLineContent(lineNumber);
551
+ }
552
+ getLineLength(lineNumber) {
553
+ this._assertNotDisposed();
554
+ if (lineNumber < 1 || lineNumber > this.getLineCount()) {
555
+ throw new BugIndicatingError('Illegal value for lineNumber');
556
+ }
557
+ return this._buffer.getLineLength(lineNumber);
558
+ }
559
+ getLinesContent() {
560
+ this._assertNotDisposed();
561
+ if (this.isTooLargeForHeapOperation()) {
562
+ throw new BugIndicatingError('Operation would exceed heap memory limits');
563
+ }
564
+ return this._buffer.getLinesContent();
565
+ }
566
+ getEOL() {
567
+ this._assertNotDisposed();
568
+ return this._buffer.getEOL();
569
+ }
570
+ getEndOfLineSequence() {
571
+ this._assertNotDisposed();
572
+ return (this._buffer.getEOL() === '\n'
573
+ ? 0 /* model.EndOfLineSequence.LF */
574
+ : 1 /* model.EndOfLineSequence.CRLF */);
575
+ }
576
+ getLineMinColumn(lineNumber) {
577
+ this._assertNotDisposed();
578
+ return 1;
579
+ }
580
+ getLineMaxColumn(lineNumber) {
581
+ this._assertNotDisposed();
582
+ if (lineNumber < 1 || lineNumber > this.getLineCount()) {
583
+ throw new BugIndicatingError('Illegal value for lineNumber');
584
+ }
585
+ return this._buffer.getLineLength(lineNumber) + 1;
586
+ }
587
+ getLineFirstNonWhitespaceColumn(lineNumber) {
588
+ this._assertNotDisposed();
589
+ if (lineNumber < 1 || lineNumber > this.getLineCount()) {
590
+ throw new BugIndicatingError('Illegal value for lineNumber');
591
+ }
592
+ return this._buffer.getLineFirstNonWhitespaceColumn(lineNumber);
593
+ }
594
+ getLineLastNonWhitespaceColumn(lineNumber) {
595
+ this._assertNotDisposed();
596
+ if (lineNumber < 1 || lineNumber > this.getLineCount()) {
597
+ throw new BugIndicatingError('Illegal value for lineNumber');
598
+ }
599
+ return this._buffer.getLineLastNonWhitespaceColumn(lineNumber);
600
+ }
601
+ /**
602
+ * Validates `range` is within buffer bounds, but allows it to sit in between surrogate pairs, etc.
603
+ * Will try to not allocate if possible.
604
+ */
605
+ _validateRangeRelaxedNoAllocations(range) {
606
+ const linesCount = this._buffer.getLineCount();
607
+ const initialStartLineNumber = range.startLineNumber;
608
+ const initialStartColumn = range.startColumn;
609
+ let startLineNumber = Math.floor((typeof initialStartLineNumber === 'number' && !isNaN(initialStartLineNumber)) ? initialStartLineNumber : 1);
610
+ let startColumn = Math.floor((typeof initialStartColumn === 'number' && !isNaN(initialStartColumn)) ? initialStartColumn : 1);
611
+ if (startLineNumber < 1) {
612
+ startLineNumber = 1;
613
+ startColumn = 1;
614
+ }
615
+ else if (startLineNumber > linesCount) {
616
+ startLineNumber = linesCount;
617
+ startColumn = this.getLineMaxColumn(startLineNumber);
618
+ }
619
+ else {
620
+ if (startColumn <= 1) {
621
+ startColumn = 1;
622
+ }
623
+ else {
624
+ const maxColumn = this.getLineMaxColumn(startLineNumber);
625
+ if (startColumn >= maxColumn) {
626
+ startColumn = maxColumn;
627
+ }
628
+ }
629
+ }
630
+ const initialEndLineNumber = range.endLineNumber;
631
+ const initialEndColumn = range.endColumn;
632
+ let endLineNumber = Math.floor((typeof initialEndLineNumber === 'number' && !isNaN(initialEndLineNumber)) ? initialEndLineNumber : 1);
633
+ let endColumn = Math.floor((typeof initialEndColumn === 'number' && !isNaN(initialEndColumn)) ? initialEndColumn : 1);
634
+ if (endLineNumber < 1) {
635
+ endLineNumber = 1;
636
+ endColumn = 1;
637
+ }
638
+ else if (endLineNumber > linesCount) {
639
+ endLineNumber = linesCount;
640
+ endColumn = this.getLineMaxColumn(endLineNumber);
641
+ }
642
+ else {
643
+ if (endColumn <= 1) {
644
+ endColumn = 1;
645
+ }
646
+ else {
647
+ const maxColumn = this.getLineMaxColumn(endLineNumber);
648
+ if (endColumn >= maxColumn) {
649
+ endColumn = maxColumn;
650
+ }
651
+ }
652
+ }
653
+ if (initialStartLineNumber === startLineNumber
654
+ && initialStartColumn === startColumn
655
+ && initialEndLineNumber === endLineNumber
656
+ && initialEndColumn === endColumn
657
+ && range instanceof Range
658
+ && !(range instanceof Selection)) {
659
+ return range;
660
+ }
661
+ return new Range(startLineNumber, startColumn, endLineNumber, endColumn);
662
+ }
663
+ _isValidPosition(lineNumber, column, validationType) {
664
+ if (typeof lineNumber !== 'number' || typeof column !== 'number') {
665
+ return false;
666
+ }
667
+ if (isNaN(lineNumber) || isNaN(column)) {
668
+ return false;
669
+ }
670
+ if (lineNumber < 1 || column < 1) {
671
+ return false;
672
+ }
673
+ if ((lineNumber | 0) !== lineNumber || (column | 0) !== column) {
674
+ return false;
675
+ }
676
+ const lineCount = this._buffer.getLineCount();
677
+ if (lineNumber > lineCount) {
678
+ return false;
679
+ }
680
+ if (column === 1) {
681
+ return true;
682
+ }
683
+ const maxColumn = this.getLineMaxColumn(lineNumber);
684
+ if (column > maxColumn) {
685
+ return false;
686
+ }
687
+ if (validationType === 1 /* StringOffsetValidationType.SurrogatePairs */) {
688
+ // !!At this point, column > 1
689
+ const charCodeBefore = this._buffer.getLineCharCode(lineNumber, column - 2);
690
+ if (strings.isHighSurrogate(charCodeBefore)) {
691
+ return false;
692
+ }
693
+ }
694
+ return true;
695
+ }
696
+ _validatePosition(_lineNumber, _column, validationType) {
697
+ const lineNumber = Math.floor((typeof _lineNumber === 'number' && !isNaN(_lineNumber)) ? _lineNumber : 1);
698
+ const column = Math.floor((typeof _column === 'number' && !isNaN(_column)) ? _column : 1);
699
+ const lineCount = this._buffer.getLineCount();
700
+ if (lineNumber < 1) {
701
+ return new Position(1, 1);
702
+ }
703
+ if (lineNumber > lineCount) {
704
+ return new Position(lineCount, this.getLineMaxColumn(lineCount));
705
+ }
706
+ if (column <= 1) {
707
+ return new Position(lineNumber, 1);
708
+ }
709
+ const maxColumn = this.getLineMaxColumn(lineNumber);
710
+ if (column >= maxColumn) {
711
+ return new Position(lineNumber, maxColumn);
712
+ }
713
+ if (validationType === 1 /* StringOffsetValidationType.SurrogatePairs */) {
714
+ // If the position would end up in the middle of a high-low surrogate pair,
715
+ // we move it to before the pair
716
+ // !!At this point, column > 1
717
+ const charCodeBefore = this._buffer.getLineCharCode(lineNumber, column - 2);
718
+ if (strings.isHighSurrogate(charCodeBefore)) {
719
+ return new Position(lineNumber, column - 1);
720
+ }
721
+ }
722
+ return new Position(lineNumber, column);
723
+ }
724
+ validatePosition(position) {
725
+ const validationType = 1 /* StringOffsetValidationType.SurrogatePairs */;
726
+ this._assertNotDisposed();
727
+ // Avoid object allocation and cover most likely case
728
+ if (position instanceof Position) {
729
+ if (this._isValidPosition(position.lineNumber, position.column, validationType)) {
730
+ return position;
731
+ }
732
+ }
733
+ return this._validatePosition(position.lineNumber, position.column, validationType);
734
+ }
735
+ _isValidRange(range, validationType) {
736
+ const startLineNumber = range.startLineNumber;
737
+ const startColumn = range.startColumn;
738
+ const endLineNumber = range.endLineNumber;
739
+ const endColumn = range.endColumn;
740
+ if (!this._isValidPosition(startLineNumber, startColumn, 0 /* StringOffsetValidationType.Relaxed */)) {
741
+ return false;
742
+ }
743
+ if (!this._isValidPosition(endLineNumber, endColumn, 0 /* StringOffsetValidationType.Relaxed */)) {
744
+ return false;
745
+ }
746
+ if (validationType === 1 /* StringOffsetValidationType.SurrogatePairs */) {
747
+ const charCodeBeforeStart = (startColumn > 1 ? this._buffer.getLineCharCode(startLineNumber, startColumn - 2) : 0);
748
+ const charCodeBeforeEnd = (endColumn > 1 && endColumn <= this._buffer.getLineLength(endLineNumber) ? this._buffer.getLineCharCode(endLineNumber, endColumn - 2) : 0);
749
+ const startInsideSurrogatePair = strings.isHighSurrogate(charCodeBeforeStart);
750
+ const endInsideSurrogatePair = strings.isHighSurrogate(charCodeBeforeEnd);
751
+ if (!startInsideSurrogatePair && !endInsideSurrogatePair) {
752
+ return true;
753
+ }
754
+ return false;
755
+ }
756
+ return true;
757
+ }
758
+ validateRange(_range) {
759
+ const validationType = 1 /* StringOffsetValidationType.SurrogatePairs */;
760
+ this._assertNotDisposed();
761
+ // Avoid object allocation and cover most likely case
762
+ if ((_range instanceof Range) && !(_range instanceof Selection)) {
763
+ if (this._isValidRange(_range, validationType)) {
764
+ return _range;
765
+ }
766
+ }
767
+ const start = this._validatePosition(_range.startLineNumber, _range.startColumn, 0 /* StringOffsetValidationType.Relaxed */);
768
+ const end = this._validatePosition(_range.endLineNumber, _range.endColumn, 0 /* StringOffsetValidationType.Relaxed */);
769
+ const startLineNumber = start.lineNumber;
770
+ const startColumn = start.column;
771
+ const endLineNumber = end.lineNumber;
772
+ const endColumn = end.column;
773
+ if (validationType === 1 /* StringOffsetValidationType.SurrogatePairs */) {
774
+ const charCodeBeforeStart = (startColumn > 1 ? this._buffer.getLineCharCode(startLineNumber, startColumn - 2) : 0);
775
+ const charCodeBeforeEnd = (endColumn > 1 && endColumn <= this._buffer.getLineLength(endLineNumber) ? this._buffer.getLineCharCode(endLineNumber, endColumn - 2) : 0);
776
+ const startInsideSurrogatePair = strings.isHighSurrogate(charCodeBeforeStart);
777
+ const endInsideSurrogatePair = strings.isHighSurrogate(charCodeBeforeEnd);
778
+ if (!startInsideSurrogatePair && !endInsideSurrogatePair) {
779
+ return new Range(startLineNumber, startColumn, endLineNumber, endColumn);
780
+ }
781
+ if (startLineNumber === endLineNumber && startColumn === endColumn) {
782
+ // do not expand a collapsed range, simply move it to a valid location
783
+ return new Range(startLineNumber, startColumn - 1, endLineNumber, endColumn - 1);
784
+ }
785
+ if (startInsideSurrogatePair && endInsideSurrogatePair) {
786
+ // expand range at both ends
787
+ return new Range(startLineNumber, startColumn - 1, endLineNumber, endColumn + 1);
788
+ }
789
+ if (startInsideSurrogatePair) {
790
+ // only expand range at the start
791
+ return new Range(startLineNumber, startColumn - 1, endLineNumber, endColumn);
792
+ }
793
+ // only expand range at the end
794
+ return new Range(startLineNumber, startColumn, endLineNumber, endColumn + 1);
795
+ }
796
+ return new Range(startLineNumber, startColumn, endLineNumber, endColumn);
797
+ }
798
+ modifyPosition(rawPosition, offset) {
799
+ this._assertNotDisposed();
800
+ const candidate = this.getOffsetAt(rawPosition) + offset;
801
+ return this.getPositionAt(Math.min(this._buffer.getLength(), Math.max(0, candidate)));
802
+ }
803
+ getFullModelRange() {
804
+ this._assertNotDisposed();
805
+ const lineCount = this.getLineCount();
806
+ return new Range(1, 1, lineCount, this.getLineMaxColumn(lineCount));
807
+ }
808
+ findMatchesLineByLine(searchRange, searchData, captureMatches, limitResultCount) {
809
+ return this._buffer.findMatchesLineByLine(searchRange, searchData, captureMatches, limitResultCount);
810
+ }
811
+ findMatches(searchString, rawSearchScope, isRegex, matchCase, wordSeparators, captureMatches, limitResultCount = LIMIT_FIND_COUNT) {
812
+ this._assertNotDisposed();
813
+ let searchRanges = null;
814
+ if (rawSearchScope !== null) {
815
+ if (!Array.isArray(rawSearchScope)) {
816
+ rawSearchScope = [rawSearchScope];
817
+ }
818
+ if (rawSearchScope.every((searchScope) => Range.isIRange(searchScope))) {
819
+ searchRanges = rawSearchScope.map((searchScope) => this.validateRange(searchScope));
820
+ }
821
+ }
822
+ if (searchRanges === null) {
823
+ searchRanges = [this.getFullModelRange()];
824
+ }
825
+ searchRanges = searchRanges.sort((d1, d2) => d1.startLineNumber - d2.startLineNumber || d1.startColumn - d2.startColumn);
826
+ const uniqueSearchRanges = [];
827
+ uniqueSearchRanges.push(searchRanges.reduce((prev, curr) => {
828
+ if (Range.areIntersecting(prev, curr)) {
829
+ return prev.plusRange(curr);
830
+ }
831
+ uniqueSearchRanges.push(prev);
832
+ return curr;
833
+ }));
834
+ let matchMapper;
835
+ if (!isRegex && searchString.indexOf('\n') < 0) {
836
+ // not regex, not multi line
837
+ const searchParams = new SearchParams(searchString, isRegex, matchCase, wordSeparators);
838
+ const searchData = searchParams.parseSearchRequest();
839
+ if (!searchData) {
840
+ return [];
841
+ }
842
+ matchMapper = (searchRange) => this.findMatchesLineByLine(searchRange, searchData, captureMatches, limitResultCount);
843
+ }
844
+ else {
845
+ matchMapper = (searchRange) => TextModelSearch.findMatches(this, new SearchParams(searchString, isRegex, matchCase, wordSeparators), searchRange, captureMatches, limitResultCount);
846
+ }
847
+ return uniqueSearchRanges.map(matchMapper).reduce((arr, matches) => arr.concat(matches), []);
848
+ }
849
+ findNextMatch(searchString, rawSearchStart, isRegex, matchCase, wordSeparators, captureMatches) {
850
+ this._assertNotDisposed();
851
+ const searchStart = this.validatePosition(rawSearchStart);
852
+ if (!isRegex && searchString.indexOf('\n') < 0) {
853
+ const searchParams = new SearchParams(searchString, isRegex, matchCase, wordSeparators);
854
+ const searchData = searchParams.parseSearchRequest();
855
+ if (!searchData) {
856
+ return null;
857
+ }
858
+ const lineCount = this.getLineCount();
859
+ let searchRange = new Range(searchStart.lineNumber, searchStart.column, lineCount, this.getLineMaxColumn(lineCount));
860
+ let ret = this.findMatchesLineByLine(searchRange, searchData, captureMatches, 1);
861
+ TextModelSearch.findNextMatch(this, new SearchParams(searchString, isRegex, matchCase, wordSeparators), searchStart, captureMatches);
862
+ if (ret.length > 0) {
863
+ return ret[0];
864
+ }
865
+ searchRange = new Range(1, 1, searchStart.lineNumber, this.getLineMaxColumn(searchStart.lineNumber));
866
+ ret = this.findMatchesLineByLine(searchRange, searchData, captureMatches, 1);
867
+ if (ret.length > 0) {
868
+ return ret[0];
869
+ }
870
+ return null;
871
+ }
872
+ return TextModelSearch.findNextMatch(this, new SearchParams(searchString, isRegex, matchCase, wordSeparators), searchStart, captureMatches);
873
+ }
874
+ findPreviousMatch(searchString, rawSearchStart, isRegex, matchCase, wordSeparators, captureMatches) {
875
+ this._assertNotDisposed();
876
+ const searchStart = this.validatePosition(rawSearchStart);
877
+ return TextModelSearch.findPreviousMatch(this, new SearchParams(searchString, isRegex, matchCase, wordSeparators), searchStart, captureMatches);
878
+ }
879
+ //#endregion
880
+ //#region Editing
881
+ pushStackElement() {
882
+ this._commandManager.pushStackElement();
883
+ }
884
+ popStackElement() {
885
+ this._commandManager.popStackElement();
886
+ }
887
+ pushEOL(eol) {
888
+ const currentEOL = (this.getEOL() === '\n' ? 0 /* model.EndOfLineSequence.LF */ : 1 /* model.EndOfLineSequence.CRLF */);
889
+ if (currentEOL === eol) {
890
+ return;
891
+ }
892
+ try {
893
+ this._onDidChangeDecorations.beginDeferredEmit();
894
+ this._eventEmitter.beginDeferredEmit();
895
+ if (this._initialUndoRedoSnapshot === null) {
896
+ this._initialUndoRedoSnapshot = this._undoRedoService.createSnapshot(this.uri);
897
+ }
898
+ this._commandManager.pushEOL(eol);
899
+ }
900
+ finally {
901
+ this._eventEmitter.endDeferredEmit();
902
+ this._onDidChangeDecorations.endDeferredEmit();
903
+ }
904
+ }
905
+ _validateEditOperation(rawOperation) {
906
+ if (rawOperation instanceof model.ValidAnnotatedEditOperation) {
907
+ return rawOperation;
908
+ }
909
+ return new model.ValidAnnotatedEditOperation(rawOperation.identifier || null, this.validateRange(rawOperation.range), rawOperation.text, rawOperation.forceMoveMarkers || false, rawOperation.isAutoWhitespaceEdit || false, rawOperation._isTracked || false);
910
+ }
911
+ _validateEditOperations(rawOperations) {
912
+ const result = [];
913
+ for (let i = 0, len = rawOperations.length; i < len; i++) {
914
+ result[i] = this._validateEditOperation(rawOperations[i]);
915
+ }
916
+ return result;
917
+ }
918
+ pushEditOperations(beforeCursorState, editOperations, cursorStateComputer, group) {
919
+ try {
920
+ this._onDidChangeDecorations.beginDeferredEmit();
921
+ this._eventEmitter.beginDeferredEmit();
922
+ return this._pushEditOperations(beforeCursorState, this._validateEditOperations(editOperations), cursorStateComputer, group);
923
+ }
924
+ finally {
925
+ this._eventEmitter.endDeferredEmit();
926
+ this._onDidChangeDecorations.endDeferredEmit();
927
+ }
928
+ }
929
+ _pushEditOperations(beforeCursorState, editOperations, cursorStateComputer, group) {
930
+ if (this._options.trimAutoWhitespace && this._trimAutoWhitespaceLines) {
931
+ // Go through each saved line number and insert a trim whitespace edit
932
+ // if it is safe to do so (no conflicts with other edits).
933
+ const incomingEdits = editOperations.map((op) => {
934
+ return {
935
+ range: this.validateRange(op.range),
936
+ text: op.text
937
+ };
938
+ });
939
+ // Sometimes, auto-formatters change ranges automatically which can cause undesired auto whitespace trimming near the cursor
940
+ // We'll use the following heuristic: if the edits occur near the cursor, then it's ok to trim auto whitespace
941
+ let editsAreNearCursors = true;
942
+ if (beforeCursorState) {
943
+ for (let i = 0, len = beforeCursorState.length; i < len; i++) {
944
+ const sel = beforeCursorState[i];
945
+ let foundEditNearSel = false;
946
+ for (let j = 0, lenJ = incomingEdits.length; j < lenJ; j++) {
947
+ const editRange = incomingEdits[j].range;
948
+ const selIsAbove = editRange.startLineNumber > sel.endLineNumber;
949
+ const selIsBelow = sel.startLineNumber > editRange.endLineNumber;
950
+ if (!selIsAbove && !selIsBelow) {
951
+ foundEditNearSel = true;
952
+ break;
953
+ }
954
+ }
955
+ if (!foundEditNearSel) {
956
+ editsAreNearCursors = false;
957
+ break;
958
+ }
959
+ }
960
+ }
961
+ if (editsAreNearCursors) {
962
+ for (let i = 0, len = this._trimAutoWhitespaceLines.length; i < len; i++) {
963
+ const trimLineNumber = this._trimAutoWhitespaceLines[i];
964
+ const maxLineColumn = this.getLineMaxColumn(trimLineNumber);
965
+ let allowTrimLine = true;
966
+ for (let j = 0, lenJ = incomingEdits.length; j < lenJ; j++) {
967
+ const editRange = incomingEdits[j].range;
968
+ const editText = incomingEdits[j].text;
969
+ if (trimLineNumber < editRange.startLineNumber || trimLineNumber > editRange.endLineNumber) {
970
+ // `trimLine` is completely outside this edit
971
+ continue;
972
+ }
973
+ // At this point:
974
+ // editRange.startLineNumber <= trimLine <= editRange.endLineNumber
975
+ if (trimLineNumber === editRange.startLineNumber && editRange.startColumn === maxLineColumn
976
+ && editRange.isEmpty() && editText && editText.length > 0 && editText.charAt(0) === '\n') {
977
+ // This edit inserts a new line (and maybe other text) after `trimLine`
978
+ continue;
979
+ }
980
+ if (trimLineNumber === editRange.startLineNumber && editRange.startColumn === 1
981
+ && editRange.isEmpty() && editText && editText.length > 0 && editText.charAt(editText.length - 1) === '\n') {
982
+ // This edit inserts a new line (and maybe other text) before `trimLine`
983
+ continue;
984
+ }
985
+ // Looks like we can't trim this line as it would interfere with an incoming edit
986
+ allowTrimLine = false;
987
+ break;
988
+ }
989
+ if (allowTrimLine) {
990
+ const trimRange = new Range(trimLineNumber, 1, trimLineNumber, maxLineColumn);
991
+ editOperations.push(new model.ValidAnnotatedEditOperation(null, trimRange, null, false, false, false));
992
+ }
993
+ }
994
+ }
995
+ this._trimAutoWhitespaceLines = null;
996
+ }
997
+ if (this._initialUndoRedoSnapshot === null) {
998
+ this._initialUndoRedoSnapshot = this._undoRedoService.createSnapshot(this.uri);
999
+ }
1000
+ return this._commandManager.pushEditOperation(beforeCursorState, editOperations, cursorStateComputer, group);
1001
+ }
1002
+ _applyUndo(changes, eol, resultingAlternativeVersionId, resultingSelection) {
1003
+ const edits = changes.map((change) => {
1004
+ const rangeStart = this.getPositionAt(change.newPosition);
1005
+ const rangeEnd = this.getPositionAt(change.newEnd);
1006
+ return {
1007
+ range: new Range(rangeStart.lineNumber, rangeStart.column, rangeEnd.lineNumber, rangeEnd.column),
1008
+ text: change.oldText
1009
+ };
1010
+ });
1011
+ this._applyUndoRedoEdits(edits, eol, true, false, resultingAlternativeVersionId, resultingSelection);
1012
+ }
1013
+ _applyRedo(changes, eol, resultingAlternativeVersionId, resultingSelection) {
1014
+ const edits = changes.map((change) => {
1015
+ const rangeStart = this.getPositionAt(change.oldPosition);
1016
+ const rangeEnd = this.getPositionAt(change.oldEnd);
1017
+ return {
1018
+ range: new Range(rangeStart.lineNumber, rangeStart.column, rangeEnd.lineNumber, rangeEnd.column),
1019
+ text: change.newText
1020
+ };
1021
+ });
1022
+ this._applyUndoRedoEdits(edits, eol, false, true, resultingAlternativeVersionId, resultingSelection);
1023
+ }
1024
+ _applyUndoRedoEdits(edits, eol, isUndoing, isRedoing, resultingAlternativeVersionId, resultingSelection) {
1025
+ try {
1026
+ this._onDidChangeDecorations.beginDeferredEmit();
1027
+ this._eventEmitter.beginDeferredEmit();
1028
+ this._isUndoing = isUndoing;
1029
+ this._isRedoing = isRedoing;
1030
+ this.applyEdits(edits, false);
1031
+ this.setEOL(eol);
1032
+ this._overwriteAlternativeVersionId(resultingAlternativeVersionId);
1033
+ }
1034
+ finally {
1035
+ this._isUndoing = false;
1036
+ this._isRedoing = false;
1037
+ this._eventEmitter.endDeferredEmit(resultingSelection);
1038
+ this._onDidChangeDecorations.endDeferredEmit();
1039
+ }
1040
+ }
1041
+ applyEdits(rawOperations, computeUndoEdits = false) {
1042
+ try {
1043
+ this._onDidChangeDecorations.beginDeferredEmit();
1044
+ this._eventEmitter.beginDeferredEmit();
1045
+ const operations = this._validateEditOperations(rawOperations);
1046
+ return this._doApplyEdits(operations, computeUndoEdits);
1047
+ }
1048
+ finally {
1049
+ this._eventEmitter.endDeferredEmit();
1050
+ this._onDidChangeDecorations.endDeferredEmit();
1051
+ }
1052
+ }
1053
+ _doApplyEdits(rawOperations, computeUndoEdits) {
1054
+ const oldLineCount = this._buffer.getLineCount();
1055
+ const result = this._buffer.applyEdits(rawOperations, this._options.trimAutoWhitespace, computeUndoEdits);
1056
+ const newLineCount = this._buffer.getLineCount();
1057
+ const contentChanges = result.changes;
1058
+ this._trimAutoWhitespaceLines = result.trimAutoWhitespaceLineNumbers;
1059
+ if (contentChanges.length !== 0) {
1060
+ // We do a first pass to update decorations
1061
+ // because we want to read decorations in the second pass
1062
+ // where we will emit content change events
1063
+ // and we want to read the final decorations
1064
+ for (let i = 0, len = contentChanges.length; i < len; i++) {
1065
+ const change = contentChanges[i];
1066
+ this._decorationsTree.acceptReplace(change.rangeOffset, change.rangeLength, change.text.length, change.forceMoveMarkers);
1067
+ }
1068
+ const rawContentChanges = [];
1069
+ this._increaseVersionId();
1070
+ let lineCount = oldLineCount;
1071
+ for (let i = 0, len = contentChanges.length; i < len; i++) {
1072
+ const change = contentChanges[i];
1073
+ const [eolCount] = countEOL(change.text);
1074
+ this._onDidChangeDecorations.fire();
1075
+ const startLineNumber = change.range.startLineNumber;
1076
+ const endLineNumber = change.range.endLineNumber;
1077
+ const deletingLinesCnt = endLineNumber - startLineNumber;
1078
+ const insertingLinesCnt = eolCount;
1079
+ const editingLinesCnt = Math.min(deletingLinesCnt, insertingLinesCnt);
1080
+ const changeLineCountDelta = (insertingLinesCnt - deletingLinesCnt);
1081
+ const currentEditStartLineNumber = newLineCount - lineCount - changeLineCountDelta + startLineNumber;
1082
+ const firstEditLineNumber = currentEditStartLineNumber;
1083
+ const lastInsertedLineNumber = currentEditStartLineNumber + insertingLinesCnt;
1084
+ const decorationsWithInjectedTextInEditedRange = this._decorationsTree.getInjectedTextInInterval(this, this.getOffsetAt(new Position(firstEditLineNumber, 1)), this.getOffsetAt(new Position(lastInsertedLineNumber, this.getLineMaxColumn(lastInsertedLineNumber))), 0);
1085
+ const injectedTextInEditedRange = LineInjectedText.fromDecorations(decorationsWithInjectedTextInEditedRange);
1086
+ const injectedTextInEditedRangeQueue = new ArrayQueue(injectedTextInEditedRange);
1087
+ for (let j = editingLinesCnt; j >= 0; j--) {
1088
+ const editLineNumber = startLineNumber + j;
1089
+ const currentEditLineNumber = currentEditStartLineNumber + j;
1090
+ injectedTextInEditedRangeQueue.takeFromEndWhile(r => r.lineNumber > currentEditLineNumber);
1091
+ const decorationsInCurrentLine = injectedTextInEditedRangeQueue.takeFromEndWhile(r => r.lineNumber === currentEditLineNumber);
1092
+ rawContentChanges.push(new ModelRawLineChanged(editLineNumber, this.getLineContent(currentEditLineNumber), decorationsInCurrentLine));
1093
+ }
1094
+ if (editingLinesCnt < deletingLinesCnt) {
1095
+ // Must delete some lines
1096
+ const spliceStartLineNumber = startLineNumber + editingLinesCnt;
1097
+ rawContentChanges.push(new ModelRawLinesDeleted(spliceStartLineNumber + 1, endLineNumber));
1098
+ }
1099
+ if (editingLinesCnt < insertingLinesCnt) {
1100
+ const injectedTextInEditedRangeQueue = new ArrayQueue(injectedTextInEditedRange);
1101
+ // Must insert some lines
1102
+ const spliceLineNumber = startLineNumber + editingLinesCnt;
1103
+ const cnt = insertingLinesCnt - editingLinesCnt;
1104
+ const fromLineNumber = newLineCount - lineCount - cnt + spliceLineNumber + 1;
1105
+ const injectedTexts = [];
1106
+ const newLines = [];
1107
+ for (let i = 0; i < cnt; i++) {
1108
+ const lineNumber = fromLineNumber + i;
1109
+ newLines[i] = this.getLineContent(lineNumber);
1110
+ injectedTextInEditedRangeQueue.takeWhile(r => r.lineNumber < lineNumber);
1111
+ injectedTexts[i] = injectedTextInEditedRangeQueue.takeWhile(r => r.lineNumber === lineNumber);
1112
+ }
1113
+ rawContentChanges.push(new ModelRawLinesInserted(spliceLineNumber + 1, startLineNumber + insertingLinesCnt, newLines, injectedTexts));
1114
+ }
1115
+ lineCount += changeLineCountDelta;
1116
+ }
1117
+ this._emitContentChangedEvent(new ModelRawContentChangedEvent(rawContentChanges, this.getVersionId(), this._isUndoing, this._isRedoing), {
1118
+ changes: contentChanges,
1119
+ eol: this._buffer.getEOL(),
1120
+ isEolChange: false,
1121
+ versionId: this.getVersionId(),
1122
+ isUndoing: this._isUndoing,
1123
+ isRedoing: this._isRedoing,
1124
+ isFlush: false
1125
+ });
1126
+ }
1127
+ return (result.reverseEdits === null ? undefined : result.reverseEdits);
1128
+ }
1129
+ undo() {
1130
+ return this._undoRedoService.undo(this.uri);
1131
+ }
1132
+ canUndo() {
1133
+ return this._undoRedoService.canUndo(this.uri);
1134
+ }
1135
+ redo() {
1136
+ return this._undoRedoService.redo(this.uri);
1137
+ }
1138
+ canRedo() {
1139
+ return this._undoRedoService.canRedo(this.uri);
1140
+ }
1141
+ //#endregion
1142
+ //#region Decorations
1143
+ handleBeforeFireDecorationsChangedEvent(affectedInjectedTextLines) {
1144
+ // This is called before the decoration changed event is fired.
1145
+ if (affectedInjectedTextLines === null || affectedInjectedTextLines.size === 0) {
1146
+ return;
1147
+ }
1148
+ const affectedLines = Array.from(affectedInjectedTextLines);
1149
+ const lineChangeEvents = affectedLines.map(lineNumber => new ModelRawLineChanged(lineNumber, this.getLineContent(lineNumber), this._getInjectedTextInLine(lineNumber)));
1150
+ this._onDidChangeInjectedText.fire(new ModelInjectedTextChangedEvent(lineChangeEvents));
1151
+ }
1152
+ changeDecorations(callback, ownerId = 0) {
1153
+ this._assertNotDisposed();
1154
+ try {
1155
+ this._onDidChangeDecorations.beginDeferredEmit();
1156
+ return this._changeDecorations(ownerId, callback);
1157
+ }
1158
+ finally {
1159
+ this._onDidChangeDecorations.endDeferredEmit();
1160
+ }
1161
+ }
1162
+ _changeDecorations(ownerId, callback) {
1163
+ const changeAccessor = {
1164
+ addDecoration: (range, options) => {
1165
+ return this._deltaDecorationsImpl(ownerId, [], [{ range: range, options: options }])[0];
1166
+ },
1167
+ changeDecoration: (id, newRange) => {
1168
+ this._changeDecorationImpl(id, newRange);
1169
+ },
1170
+ changeDecorationOptions: (id, options) => {
1171
+ this._changeDecorationOptionsImpl(id, _normalizeOptions(options));
1172
+ },
1173
+ removeDecoration: (id) => {
1174
+ this._deltaDecorationsImpl(ownerId, [id], []);
1175
+ },
1176
+ deltaDecorations: (oldDecorations, newDecorations) => {
1177
+ if (oldDecorations.length === 0 && newDecorations.length === 0) {
1178
+ // nothing to do
1179
+ return [];
1180
+ }
1181
+ return this._deltaDecorationsImpl(ownerId, oldDecorations, newDecorations);
1182
+ }
1183
+ };
1184
+ let result = null;
1185
+ try {
1186
+ result = callback(changeAccessor);
1187
+ }
1188
+ catch (e) {
1189
+ onUnexpectedError(e);
1190
+ }
1191
+ // Invalidate change accessor
1192
+ changeAccessor.addDecoration = invalidFunc;
1193
+ changeAccessor.changeDecoration = invalidFunc;
1194
+ changeAccessor.changeDecorationOptions = invalidFunc;
1195
+ changeAccessor.removeDecoration = invalidFunc;
1196
+ changeAccessor.deltaDecorations = invalidFunc;
1197
+ return result;
1198
+ }
1199
+ deltaDecorations(oldDecorations, newDecorations, ownerId = 0) {
1200
+ this._assertNotDisposed();
1201
+ if (!oldDecorations) {
1202
+ oldDecorations = [];
1203
+ }
1204
+ if (oldDecorations.length === 0 && newDecorations.length === 0) {
1205
+ // nothing to do
1206
+ return [];
1207
+ }
1208
+ try {
1209
+ this._deltaDecorationCallCnt++;
1210
+ if (this._deltaDecorationCallCnt > 1) {
1211
+ console.warn(`Invoking deltaDecorations recursively could lead to leaking decorations.`);
1212
+ onUnexpectedError(new Error(`Invoking deltaDecorations recursively could lead to leaking decorations.`));
1213
+ }
1214
+ this._onDidChangeDecorations.beginDeferredEmit();
1215
+ return this._deltaDecorationsImpl(ownerId, oldDecorations, newDecorations);
1216
+ }
1217
+ finally {
1218
+ this._onDidChangeDecorations.endDeferredEmit();
1219
+ this._deltaDecorationCallCnt--;
1220
+ }
1221
+ }
1222
+ _getTrackedRange(id) {
1223
+ return this.getDecorationRange(id);
1224
+ }
1225
+ _setTrackedRange(id, newRange, newStickiness) {
1226
+ const node = (id ? this._decorations[id] : null);
1227
+ if (!node) {
1228
+ if (!newRange) {
1229
+ // node doesn't exist, the request is to delete => nothing to do
1230
+ return null;
1231
+ }
1232
+ // node doesn't exist, the request is to set => add the tracked range
1233
+ return this._deltaDecorationsImpl(0, [], [{ range: newRange, options: TRACKED_RANGE_OPTIONS[newStickiness] }], true)[0];
1234
+ }
1235
+ if (!newRange) {
1236
+ // node exists, the request is to delete => delete node
1237
+ this._decorationsTree.delete(node);
1238
+ delete this._decorations[node.id];
1239
+ return null;
1240
+ }
1241
+ // node exists, the request is to set => change the tracked range and its options
1242
+ const range = this._validateRangeRelaxedNoAllocations(newRange);
1243
+ const startOffset = this._buffer.getOffsetAt(range.startLineNumber, range.startColumn);
1244
+ const endOffset = this._buffer.getOffsetAt(range.endLineNumber, range.endColumn);
1245
+ this._decorationsTree.delete(node);
1246
+ node.reset(this.getVersionId(), startOffset, endOffset, range);
1247
+ node.setOptions(TRACKED_RANGE_OPTIONS[newStickiness]);
1248
+ this._decorationsTree.insert(node);
1249
+ return node.id;
1250
+ }
1251
+ removeAllDecorationsWithOwnerId(ownerId) {
1252
+ if (this._isDisposed) {
1253
+ return;
1254
+ }
1255
+ const nodes = this._decorationsTree.collectNodesFromOwner(ownerId);
1256
+ for (let i = 0, len = nodes.length; i < len; i++) {
1257
+ const node = nodes[i];
1258
+ this._decorationsTree.delete(node);
1259
+ delete this._decorations[node.id];
1260
+ }
1261
+ }
1262
+ getDecorationOptions(decorationId) {
1263
+ const node = this._decorations[decorationId];
1264
+ if (!node) {
1265
+ return null;
1266
+ }
1267
+ return node.options;
1268
+ }
1269
+ getDecorationRange(decorationId) {
1270
+ const node = this._decorations[decorationId];
1271
+ if (!node) {
1272
+ return null;
1273
+ }
1274
+ return this._decorationsTree.getNodeRange(this, node);
1275
+ }
1276
+ getLineDecorations(lineNumber, ownerId = 0, filterOutValidation = false) {
1277
+ if (lineNumber < 1 || lineNumber > this.getLineCount()) {
1278
+ return [];
1279
+ }
1280
+ return this.getLinesDecorations(lineNumber, lineNumber, ownerId, filterOutValidation);
1281
+ }
1282
+ getLinesDecorations(_startLineNumber, _endLineNumber, ownerId = 0, filterOutValidation = false, onlyMarginDecorations = false) {
1283
+ const lineCount = this.getLineCount();
1284
+ const startLineNumber = Math.min(lineCount, Math.max(1, _startLineNumber));
1285
+ const endLineNumber = Math.min(lineCount, Math.max(1, _endLineNumber));
1286
+ const endColumn = this.getLineMaxColumn(endLineNumber);
1287
+ const range = new Range(startLineNumber, 1, endLineNumber, endColumn);
1288
+ const decorations = this._getDecorationsInRange(range, ownerId, filterOutValidation, onlyMarginDecorations);
1289
+ pushMany(decorations, this._decorationProvider.getDecorationsInRange(range, ownerId, filterOutValidation));
1290
+ return decorations;
1291
+ }
1292
+ getDecorationsInRange(range, ownerId = 0, filterOutValidation = false, onlyMinimapDecorations = false, onlyMarginDecorations = false) {
1293
+ const validatedRange = this.validateRange(range);
1294
+ const decorations = this._getDecorationsInRange(validatedRange, ownerId, filterOutValidation, onlyMarginDecorations);
1295
+ pushMany(decorations, this._decorationProvider.getDecorationsInRange(validatedRange, ownerId, filterOutValidation, onlyMinimapDecorations));
1296
+ return decorations;
1297
+ }
1298
+ getOverviewRulerDecorations(ownerId = 0, filterOutValidation = false) {
1299
+ return this._decorationsTree.getAll(this, ownerId, filterOutValidation, true, false);
1300
+ }
1301
+ getInjectedTextDecorations(ownerId = 0) {
1302
+ return this._decorationsTree.getAllInjectedText(this, ownerId);
1303
+ }
1304
+ _getInjectedTextInLine(lineNumber) {
1305
+ const startOffset = this._buffer.getOffsetAt(lineNumber, 1);
1306
+ const endOffset = startOffset + this._buffer.getLineLength(lineNumber);
1307
+ const result = this._decorationsTree.getInjectedTextInInterval(this, startOffset, endOffset, 0);
1308
+ return LineInjectedText.fromDecorations(result).filter(t => t.lineNumber === lineNumber);
1309
+ }
1310
+ getAllDecorations(ownerId = 0, filterOutValidation = false) {
1311
+ let result = this._decorationsTree.getAll(this, ownerId, filterOutValidation, false, false);
1312
+ result = result.concat(this._decorationProvider.getAllDecorations(ownerId, filterOutValidation));
1313
+ return result;
1314
+ }
1315
+ getAllMarginDecorations(ownerId = 0) {
1316
+ return this._decorationsTree.getAll(this, ownerId, false, false, true);
1317
+ }
1318
+ _getDecorationsInRange(filterRange, filterOwnerId, filterOutValidation, onlyMarginDecorations) {
1319
+ const startOffset = this._buffer.getOffsetAt(filterRange.startLineNumber, filterRange.startColumn);
1320
+ const endOffset = this._buffer.getOffsetAt(filterRange.endLineNumber, filterRange.endColumn);
1321
+ return this._decorationsTree.getAllInInterval(this, startOffset, endOffset, filterOwnerId, filterOutValidation, onlyMarginDecorations);
1322
+ }
1323
+ getRangeAt(start, end) {
1324
+ return this._buffer.getRangeAt(start, end - start);
1325
+ }
1326
+ _changeDecorationImpl(decorationId, _range) {
1327
+ const node = this._decorations[decorationId];
1328
+ if (!node) {
1329
+ return;
1330
+ }
1331
+ if (node.options.after) {
1332
+ const oldRange = this.getDecorationRange(decorationId);
1333
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(oldRange.endLineNumber);
1334
+ }
1335
+ if (node.options.before) {
1336
+ const oldRange = this.getDecorationRange(decorationId);
1337
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(oldRange.startLineNumber);
1338
+ }
1339
+ const range = this._validateRangeRelaxedNoAllocations(_range);
1340
+ const startOffset = this._buffer.getOffsetAt(range.startLineNumber, range.startColumn);
1341
+ const endOffset = this._buffer.getOffsetAt(range.endLineNumber, range.endColumn);
1342
+ this._decorationsTree.delete(node);
1343
+ node.reset(this.getVersionId(), startOffset, endOffset, range);
1344
+ this._decorationsTree.insert(node);
1345
+ this._onDidChangeDecorations.checkAffectedAndFire(node.options);
1346
+ if (node.options.after) {
1347
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(range.endLineNumber);
1348
+ }
1349
+ if (node.options.before) {
1350
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(range.startLineNumber);
1351
+ }
1352
+ }
1353
+ _changeDecorationOptionsImpl(decorationId, options) {
1354
+ const node = this._decorations[decorationId];
1355
+ if (!node) {
1356
+ return;
1357
+ }
1358
+ const nodeWasInOverviewRuler = (node.options.overviewRuler && node.options.overviewRuler.color ? true : false);
1359
+ const nodeIsInOverviewRuler = (options.overviewRuler && options.overviewRuler.color ? true : false);
1360
+ this._onDidChangeDecorations.checkAffectedAndFire(node.options);
1361
+ this._onDidChangeDecorations.checkAffectedAndFire(options);
1362
+ if (node.options.after || options.after) {
1363
+ const nodeRange = this._decorationsTree.getNodeRange(this, node);
1364
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(nodeRange.endLineNumber);
1365
+ }
1366
+ if (node.options.before || options.before) {
1367
+ const nodeRange = this._decorationsTree.getNodeRange(this, node);
1368
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(nodeRange.startLineNumber);
1369
+ }
1370
+ const movedInOverviewRuler = nodeWasInOverviewRuler !== nodeIsInOverviewRuler;
1371
+ const changedWhetherInjectedText = isOptionsInjectedText(options) !== isNodeInjectedText(node);
1372
+ if (movedInOverviewRuler || changedWhetherInjectedText) {
1373
+ this._decorationsTree.delete(node);
1374
+ node.setOptions(options);
1375
+ this._decorationsTree.insert(node);
1376
+ }
1377
+ else {
1378
+ node.setOptions(options);
1379
+ }
1380
+ }
1381
+ _deltaDecorationsImpl(ownerId, oldDecorationsIds, newDecorations, suppressEvents = false) {
1382
+ const versionId = this.getVersionId();
1383
+ const oldDecorationsLen = oldDecorationsIds.length;
1384
+ let oldDecorationIndex = 0;
1385
+ const newDecorationsLen = newDecorations.length;
1386
+ let newDecorationIndex = 0;
1387
+ this._onDidChangeDecorations.beginDeferredEmit();
1388
+ try {
1389
+ const result = new Array(newDecorationsLen);
1390
+ while (oldDecorationIndex < oldDecorationsLen || newDecorationIndex < newDecorationsLen) {
1391
+ let node = null;
1392
+ if (oldDecorationIndex < oldDecorationsLen) {
1393
+ // (1) get ourselves an old node
1394
+ do {
1395
+ node = this._decorations[oldDecorationsIds[oldDecorationIndex++]];
1396
+ } while (!node && oldDecorationIndex < oldDecorationsLen);
1397
+ // (2) remove the node from the tree (if it exists)
1398
+ if (node) {
1399
+ if (node.options.after) {
1400
+ const nodeRange = this._decorationsTree.getNodeRange(this, node);
1401
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(nodeRange.endLineNumber);
1402
+ }
1403
+ if (node.options.before) {
1404
+ const nodeRange = this._decorationsTree.getNodeRange(this, node);
1405
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(nodeRange.startLineNumber);
1406
+ }
1407
+ this._decorationsTree.delete(node);
1408
+ if (!suppressEvents) {
1409
+ this._onDidChangeDecorations.checkAffectedAndFire(node.options);
1410
+ }
1411
+ }
1412
+ }
1413
+ if (newDecorationIndex < newDecorationsLen) {
1414
+ // (3) create a new node if necessary
1415
+ if (!node) {
1416
+ const internalDecorationId = (++this._lastDecorationId);
1417
+ const decorationId = `${this._instanceId};${internalDecorationId}`;
1418
+ node = new IntervalNode(decorationId, 0, 0);
1419
+ this._decorations[decorationId] = node;
1420
+ }
1421
+ // (4) initialize node
1422
+ const newDecoration = newDecorations[newDecorationIndex];
1423
+ const range = this._validateRangeRelaxedNoAllocations(newDecoration.range);
1424
+ const options = _normalizeOptions(newDecoration.options);
1425
+ const startOffset = this._buffer.getOffsetAt(range.startLineNumber, range.startColumn);
1426
+ const endOffset = this._buffer.getOffsetAt(range.endLineNumber, range.endColumn);
1427
+ node.ownerId = ownerId;
1428
+ node.reset(versionId, startOffset, endOffset, range);
1429
+ node.setOptions(options);
1430
+ if (node.options.after) {
1431
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(range.endLineNumber);
1432
+ }
1433
+ if (node.options.before) {
1434
+ this._onDidChangeDecorations.recordLineAffectedByInjectedText(range.startLineNumber);
1435
+ }
1436
+ if (!suppressEvents) {
1437
+ this._onDidChangeDecorations.checkAffectedAndFire(options);
1438
+ }
1439
+ this._decorationsTree.insert(node);
1440
+ result[newDecorationIndex] = node.id;
1441
+ newDecorationIndex++;
1442
+ }
1443
+ else {
1444
+ if (node) {
1445
+ delete this._decorations[node.id];
1446
+ }
1447
+ }
1448
+ }
1449
+ return result;
1450
+ }
1451
+ finally {
1452
+ this._onDidChangeDecorations.endDeferredEmit();
1453
+ }
1454
+ }
1455
+ //#endregion
1456
+ //#region Tokenization
1457
+ // TODO move them to the tokenization part.
1458
+ getLanguageId() {
1459
+ return this.tokenization.getLanguageId();
1460
+ }
1461
+ setLanguage(languageIdOrSelection, source) {
1462
+ if (typeof languageIdOrSelection === 'string') {
1463
+ this._languageSelectionListener.clear();
1464
+ this._setLanguage(languageIdOrSelection, source);
1465
+ }
1466
+ else {
1467
+ this._languageSelectionListener.value = languageIdOrSelection.onDidChange(() => this._setLanguage(languageIdOrSelection.languageId, source));
1468
+ this._setLanguage(languageIdOrSelection.languageId, source);
1469
+ }
1470
+ }
1471
+ _setLanguage(languageId, source) {
1472
+ this.tokenization.setLanguageId(languageId, source);
1473
+ this._languageService.requestRichLanguageFeatures(languageId);
1474
+ }
1475
+ getLanguageIdAtPosition(lineNumber, column) {
1476
+ return this.tokenization.getLanguageIdAtPosition(lineNumber, column);
1477
+ }
1478
+ getWordAtPosition(position) {
1479
+ return this._tokenizationTextModelPart.getWordAtPosition(position);
1480
+ }
1481
+ getWordUntilPosition(position) {
1482
+ return this._tokenizationTextModelPart.getWordUntilPosition(position);
1483
+ }
1484
+ //#endregion
1485
+ normalizePosition(position, affinity) {
1486
+ return position;
1487
+ }
1488
+ /**
1489
+ * Gets the column at which indentation stops at a given line.
1490
+ * @internal
1491
+ */
1492
+ getLineIndentColumn(lineNumber) {
1493
+ // Columns start with 1.
1494
+ return indentOfLine(this.getLineContent(lineNumber)) + 1;
1495
+ }
1496
+ };
1497
+ TextModel = TextModel_1 = __decorate([
1498
+ __param(4, IUndoRedoService),
1499
+ __param(5, ILanguageService),
1500
+ __param(6, ILanguageConfigurationService),
1501
+ __param(7, IInstantiationService)
1502
+ ], TextModel);
1503
+ export { TextModel };
1504
+ export function indentOfLine(line) {
1505
+ let indent = 0;
1506
+ for (const c of line) {
1507
+ if (c === ' ' || c === '\t') {
1508
+ indent++;
1509
+ }
1510
+ else {
1511
+ break;
1512
+ }
1513
+ }
1514
+ return indent;
1515
+ }
1516
+ //#region Decorations
1517
+ function isNodeInOverviewRuler(node) {
1518
+ return (node.options.overviewRuler && node.options.overviewRuler.color ? true : false);
1519
+ }
1520
+ function isOptionsInjectedText(options) {
1521
+ return !!options.after || !!options.before;
1522
+ }
1523
+ function isNodeInjectedText(node) {
1524
+ return !!node.options.after || !!node.options.before;
1525
+ }
1526
+ class DecorationsTrees {
1527
+ constructor() {
1528
+ this._decorationsTree0 = new IntervalTree();
1529
+ this._decorationsTree1 = new IntervalTree();
1530
+ this._injectedTextDecorationsTree = new IntervalTree();
1531
+ }
1532
+ ensureAllNodesHaveRanges(host) {
1533
+ this.getAll(host, 0, false, false, false);
1534
+ }
1535
+ _ensureNodesHaveRanges(host, nodes) {
1536
+ for (const node of nodes) {
1537
+ if (node.range === null) {
1538
+ node.range = host.getRangeAt(node.cachedAbsoluteStart, node.cachedAbsoluteEnd);
1539
+ }
1540
+ }
1541
+ return nodes;
1542
+ }
1543
+ getAllInInterval(host, start, end, filterOwnerId, filterOutValidation, onlyMarginDecorations) {
1544
+ const versionId = host.getVersionId();
1545
+ const result = this._intervalSearch(start, end, filterOwnerId, filterOutValidation, versionId, onlyMarginDecorations);
1546
+ return this._ensureNodesHaveRanges(host, result);
1547
+ }
1548
+ _intervalSearch(start, end, filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations) {
1549
+ const r0 = this._decorationsTree0.intervalSearch(start, end, filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations);
1550
+ const r1 = this._decorationsTree1.intervalSearch(start, end, filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations);
1551
+ const r2 = this._injectedTextDecorationsTree.intervalSearch(start, end, filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations);
1552
+ return r0.concat(r1).concat(r2);
1553
+ }
1554
+ getInjectedTextInInterval(host, start, end, filterOwnerId) {
1555
+ const versionId = host.getVersionId();
1556
+ const result = this._injectedTextDecorationsTree.intervalSearch(start, end, filterOwnerId, false, versionId, false);
1557
+ return this._ensureNodesHaveRanges(host, result).filter((i) => i.options.showIfCollapsed || !i.range.isEmpty());
1558
+ }
1559
+ getAllInjectedText(host, filterOwnerId) {
1560
+ const versionId = host.getVersionId();
1561
+ const result = this._injectedTextDecorationsTree.search(filterOwnerId, false, versionId, false);
1562
+ return this._ensureNodesHaveRanges(host, result).filter((i) => i.options.showIfCollapsed || !i.range.isEmpty());
1563
+ }
1564
+ getAll(host, filterOwnerId, filterOutValidation, overviewRulerOnly, onlyMarginDecorations) {
1565
+ const versionId = host.getVersionId();
1566
+ const result = this._search(filterOwnerId, filterOutValidation, overviewRulerOnly, versionId, onlyMarginDecorations);
1567
+ return this._ensureNodesHaveRanges(host, result);
1568
+ }
1569
+ _search(filterOwnerId, filterOutValidation, overviewRulerOnly, cachedVersionId, onlyMarginDecorations) {
1570
+ if (overviewRulerOnly) {
1571
+ return this._decorationsTree1.search(filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations);
1572
+ }
1573
+ else {
1574
+ const r0 = this._decorationsTree0.search(filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations);
1575
+ const r1 = this._decorationsTree1.search(filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations);
1576
+ const r2 = this._injectedTextDecorationsTree.search(filterOwnerId, filterOutValidation, cachedVersionId, onlyMarginDecorations);
1577
+ return r0.concat(r1).concat(r2);
1578
+ }
1579
+ }
1580
+ collectNodesFromOwner(ownerId) {
1581
+ const r0 = this._decorationsTree0.collectNodesFromOwner(ownerId);
1582
+ const r1 = this._decorationsTree1.collectNodesFromOwner(ownerId);
1583
+ const r2 = this._injectedTextDecorationsTree.collectNodesFromOwner(ownerId);
1584
+ return r0.concat(r1).concat(r2);
1585
+ }
1586
+ collectNodesPostOrder() {
1587
+ const r0 = this._decorationsTree0.collectNodesPostOrder();
1588
+ const r1 = this._decorationsTree1.collectNodesPostOrder();
1589
+ const r2 = this._injectedTextDecorationsTree.collectNodesPostOrder();
1590
+ return r0.concat(r1).concat(r2);
1591
+ }
1592
+ insert(node) {
1593
+ if (isNodeInjectedText(node)) {
1594
+ this._injectedTextDecorationsTree.insert(node);
1595
+ }
1596
+ else if (isNodeInOverviewRuler(node)) {
1597
+ this._decorationsTree1.insert(node);
1598
+ }
1599
+ else {
1600
+ this._decorationsTree0.insert(node);
1601
+ }
1602
+ }
1603
+ delete(node) {
1604
+ if (isNodeInjectedText(node)) {
1605
+ this._injectedTextDecorationsTree.delete(node);
1606
+ }
1607
+ else if (isNodeInOverviewRuler(node)) {
1608
+ this._decorationsTree1.delete(node);
1609
+ }
1610
+ else {
1611
+ this._decorationsTree0.delete(node);
1612
+ }
1613
+ }
1614
+ getNodeRange(host, node) {
1615
+ const versionId = host.getVersionId();
1616
+ if (node.cachedVersionId !== versionId) {
1617
+ this._resolveNode(node, versionId);
1618
+ }
1619
+ if (node.range === null) {
1620
+ node.range = host.getRangeAt(node.cachedAbsoluteStart, node.cachedAbsoluteEnd);
1621
+ }
1622
+ return node.range;
1623
+ }
1624
+ _resolveNode(node, cachedVersionId) {
1625
+ if (isNodeInjectedText(node)) {
1626
+ this._injectedTextDecorationsTree.resolveNode(node, cachedVersionId);
1627
+ }
1628
+ else if (isNodeInOverviewRuler(node)) {
1629
+ this._decorationsTree1.resolveNode(node, cachedVersionId);
1630
+ }
1631
+ else {
1632
+ this._decorationsTree0.resolveNode(node, cachedVersionId);
1633
+ }
1634
+ }
1635
+ acceptReplace(offset, length, textLength, forceMoveMarkers) {
1636
+ this._decorationsTree0.acceptReplace(offset, length, textLength, forceMoveMarkers);
1637
+ this._decorationsTree1.acceptReplace(offset, length, textLength, forceMoveMarkers);
1638
+ this._injectedTextDecorationsTree.acceptReplace(offset, length, textLength, forceMoveMarkers);
1639
+ }
1640
+ }
1641
+ function cleanClassName(className) {
1642
+ return className.replace(/[^a-z0-9\-_]/gi, ' ');
1643
+ }
1644
+ class DecorationOptions {
1645
+ constructor(options) {
1646
+ this.color = options.color || '';
1647
+ this.darkColor = options.darkColor || '';
1648
+ }
1649
+ }
1650
+ export class ModelDecorationOverviewRulerOptions extends DecorationOptions {
1651
+ constructor(options) {
1652
+ super(options);
1653
+ this._resolvedColor = null;
1654
+ this.position = (typeof options.position === 'number' ? options.position : model.OverviewRulerLane.Center);
1655
+ }
1656
+ getColor(theme) {
1657
+ if (!this._resolvedColor) {
1658
+ if (theme.type !== 'light' && this.darkColor) {
1659
+ this._resolvedColor = this._resolveColor(this.darkColor, theme);
1660
+ }
1661
+ else {
1662
+ this._resolvedColor = this._resolveColor(this.color, theme);
1663
+ }
1664
+ }
1665
+ return this._resolvedColor;
1666
+ }
1667
+ invalidateCachedColor() {
1668
+ this._resolvedColor = null;
1669
+ }
1670
+ _resolveColor(color, theme) {
1671
+ if (typeof color === 'string') {
1672
+ return color;
1673
+ }
1674
+ const c = color ? theme.getColor(color.id) : null;
1675
+ if (!c) {
1676
+ return '';
1677
+ }
1678
+ return c.toString();
1679
+ }
1680
+ }
1681
+ export class ModelDecorationGlyphMarginOptions {
1682
+ constructor(options) {
1683
+ this.position = options?.position ?? model.GlyphMarginLane.Center;
1684
+ this.persistLane = options?.persistLane;
1685
+ }
1686
+ }
1687
+ export class ModelDecorationMinimapOptions extends DecorationOptions {
1688
+ constructor(options) {
1689
+ super(options);
1690
+ this.position = options.position;
1691
+ this.sectionHeaderStyle = options.sectionHeaderStyle ?? null;
1692
+ this.sectionHeaderText = options.sectionHeaderText ?? null;
1693
+ }
1694
+ getColor(theme) {
1695
+ if (!this._resolvedColor) {
1696
+ if (theme.type !== 'light' && this.darkColor) {
1697
+ this._resolvedColor = this._resolveColor(this.darkColor, theme);
1698
+ }
1699
+ else {
1700
+ this._resolvedColor = this._resolveColor(this.color, theme);
1701
+ }
1702
+ }
1703
+ return this._resolvedColor;
1704
+ }
1705
+ invalidateCachedColor() {
1706
+ this._resolvedColor = undefined;
1707
+ }
1708
+ _resolveColor(color, theme) {
1709
+ if (typeof color === 'string') {
1710
+ return Color.fromHex(color);
1711
+ }
1712
+ return theme.getColor(color.id);
1713
+ }
1714
+ }
1715
+ export class ModelDecorationInjectedTextOptions {
1716
+ static from(options) {
1717
+ if (options instanceof ModelDecorationInjectedTextOptions) {
1718
+ return options;
1719
+ }
1720
+ return new ModelDecorationInjectedTextOptions(options);
1721
+ }
1722
+ constructor(options) {
1723
+ this.content = options.content || '';
1724
+ this.inlineClassName = options.inlineClassName || null;
1725
+ this.inlineClassNameAffectsLetterSpacing = options.inlineClassNameAffectsLetterSpacing || false;
1726
+ this.attachedData = options.attachedData || null;
1727
+ this.cursorStops = options.cursorStops || null;
1728
+ }
1729
+ }
1730
+ export class ModelDecorationOptions {
1731
+ static register(options) {
1732
+ return new ModelDecorationOptions(options);
1733
+ }
1734
+ static createDynamic(options) {
1735
+ return new ModelDecorationOptions(options);
1736
+ }
1737
+ constructor(options) {
1738
+ this.description = options.description;
1739
+ this.blockClassName = options.blockClassName ? cleanClassName(options.blockClassName) : null;
1740
+ this.blockDoesNotCollapse = options.blockDoesNotCollapse ?? null;
1741
+ this.blockIsAfterEnd = options.blockIsAfterEnd ?? null;
1742
+ this.blockPadding = options.blockPadding ?? null;
1743
+ this.stickiness = options.stickiness || 0 /* model.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges */;
1744
+ this.zIndex = options.zIndex || 0;
1745
+ this.className = options.className ? cleanClassName(options.className) : null;
1746
+ this.shouldFillLineOnLineBreak = options.shouldFillLineOnLineBreak ?? null;
1747
+ this.hoverMessage = options.hoverMessage || null;
1748
+ this.glyphMarginHoverMessage = options.glyphMarginHoverMessage || null;
1749
+ this.lineNumberHoverMessage = options.lineNumberHoverMessage || null;
1750
+ this.isWholeLine = options.isWholeLine || false;
1751
+ this.showIfCollapsed = options.showIfCollapsed || false;
1752
+ this.collapseOnReplaceEdit = options.collapseOnReplaceEdit || false;
1753
+ this.overviewRuler = options.overviewRuler ? new ModelDecorationOverviewRulerOptions(options.overviewRuler) : null;
1754
+ this.minimap = options.minimap ? new ModelDecorationMinimapOptions(options.minimap) : null;
1755
+ this.glyphMargin = options.glyphMarginClassName ? new ModelDecorationGlyphMarginOptions(options.glyphMargin) : null;
1756
+ this.glyphMarginClassName = options.glyphMarginClassName ? cleanClassName(options.glyphMarginClassName) : null;
1757
+ this.linesDecorationsClassName = options.linesDecorationsClassName ? cleanClassName(options.linesDecorationsClassName) : null;
1758
+ this.lineNumberClassName = options.lineNumberClassName ? cleanClassName(options.lineNumberClassName) : null;
1759
+ this.linesDecorationsTooltip = options.linesDecorationsTooltip ? strings.htmlAttributeEncodeValue(options.linesDecorationsTooltip) : null;
1760
+ this.firstLineDecorationClassName = options.firstLineDecorationClassName ? cleanClassName(options.firstLineDecorationClassName) : null;
1761
+ this.marginClassName = options.marginClassName ? cleanClassName(options.marginClassName) : null;
1762
+ this.inlineClassName = options.inlineClassName ? cleanClassName(options.inlineClassName) : null;
1763
+ this.inlineClassNameAffectsLetterSpacing = options.inlineClassNameAffectsLetterSpacing || false;
1764
+ this.beforeContentClassName = options.beforeContentClassName ? cleanClassName(options.beforeContentClassName) : null;
1765
+ this.afterContentClassName = options.afterContentClassName ? cleanClassName(options.afterContentClassName) : null;
1766
+ this.after = options.after ? ModelDecorationInjectedTextOptions.from(options.after) : null;
1767
+ this.before = options.before ? ModelDecorationInjectedTextOptions.from(options.before) : null;
1768
+ this.hideInCommentTokens = options.hideInCommentTokens ?? false;
1769
+ this.hideInStringTokens = options.hideInStringTokens ?? false;
1770
+ }
1771
+ }
1772
+ ModelDecorationOptions.EMPTY = ModelDecorationOptions.register({ description: 'empty' });
1773
+ /**
1774
+ * The order carefully matches the values of the enum.
1775
+ */
1776
+ const TRACKED_RANGE_OPTIONS = [
1777
+ ModelDecorationOptions.register({ description: 'tracked-range-always-grows-when-typing-at-edges', stickiness: 0 /* model.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges */ }),
1778
+ ModelDecorationOptions.register({ description: 'tracked-range-never-grows-when-typing-at-edges', stickiness: 1 /* model.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */ }),
1779
+ ModelDecorationOptions.register({ description: 'tracked-range-grows-only-when-typing-before', stickiness: 2 /* model.TrackedRangeStickiness.GrowsOnlyWhenTypingBefore */ }),
1780
+ ModelDecorationOptions.register({ description: 'tracked-range-grows-only-when-typing-after', stickiness: 3 /* model.TrackedRangeStickiness.GrowsOnlyWhenTypingAfter */ }),
1781
+ ];
1782
+ function _normalizeOptions(options) {
1783
+ if (options instanceof ModelDecorationOptions) {
1784
+ return options;
1785
+ }
1786
+ return ModelDecorationOptions.createDynamic(options);
1787
+ }
1788
+ class DidChangeDecorationsEmitter extends Disposable {
1789
+ constructor(handleBeforeFire) {
1790
+ super();
1791
+ this.handleBeforeFire = handleBeforeFire;
1792
+ this._actual = this._register(new Emitter());
1793
+ this.event = this._actual.event;
1794
+ this._affectedInjectedTextLines = null;
1795
+ this._deferredCnt = 0;
1796
+ this._shouldFireDeferred = false;
1797
+ this._affectsMinimap = false;
1798
+ this._affectsOverviewRuler = false;
1799
+ this._affectsGlyphMargin = false;
1800
+ this._affectsLineNumber = false;
1801
+ }
1802
+ beginDeferredEmit() {
1803
+ this._deferredCnt++;
1804
+ }
1805
+ endDeferredEmit() {
1806
+ this._deferredCnt--;
1807
+ if (this._deferredCnt === 0) {
1808
+ if (this._shouldFireDeferred) {
1809
+ this.doFire();
1810
+ }
1811
+ this._affectedInjectedTextLines?.clear();
1812
+ this._affectedInjectedTextLines = null;
1813
+ }
1814
+ }
1815
+ recordLineAffectedByInjectedText(lineNumber) {
1816
+ if (!this._affectedInjectedTextLines) {
1817
+ this._affectedInjectedTextLines = new Set();
1818
+ }
1819
+ this._affectedInjectedTextLines.add(lineNumber);
1820
+ }
1821
+ checkAffectedAndFire(options) {
1822
+ this._affectsMinimap ||= !!options.minimap?.position;
1823
+ this._affectsOverviewRuler ||= !!options.overviewRuler?.color;
1824
+ this._affectsGlyphMargin ||= !!options.glyphMarginClassName;
1825
+ this._affectsLineNumber ||= !!options.lineNumberClassName;
1826
+ this.tryFire();
1827
+ }
1828
+ fire() {
1829
+ this._affectsMinimap = true;
1830
+ this._affectsOverviewRuler = true;
1831
+ this._affectsGlyphMargin = true;
1832
+ this.tryFire();
1833
+ }
1834
+ tryFire() {
1835
+ if (this._deferredCnt === 0) {
1836
+ this.doFire();
1837
+ }
1838
+ else {
1839
+ this._shouldFireDeferred = true;
1840
+ }
1841
+ }
1842
+ doFire() {
1843
+ this.handleBeforeFire(this._affectedInjectedTextLines);
1844
+ const event = {
1845
+ affectsMinimap: this._affectsMinimap,
1846
+ affectsOverviewRuler: this._affectsOverviewRuler,
1847
+ affectsGlyphMargin: this._affectsGlyphMargin,
1848
+ affectsLineNumber: this._affectsLineNumber,
1849
+ };
1850
+ this._shouldFireDeferred = false;
1851
+ this._affectsMinimap = false;
1852
+ this._affectsOverviewRuler = false;
1853
+ this._affectsGlyphMargin = false;
1854
+ this._actual.fire(event);
1855
+ }
1856
+ }
1857
+ //#endregion
1858
+ class DidChangeContentEmitter extends Disposable {
1859
+ constructor() {
1860
+ super();
1861
+ /**
1862
+ * Both `fastEvent` and `slowEvent` work the same way and contain the same events, but first we invoke `fastEvent` and then `slowEvent`.
1863
+ */
1864
+ this._fastEmitter = this._register(new Emitter());
1865
+ this.fastEvent = this._fastEmitter.event;
1866
+ this._slowEmitter = this._register(new Emitter());
1867
+ this.slowEvent = this._slowEmitter.event;
1868
+ this._deferredCnt = 0;
1869
+ this._deferredEvent = null;
1870
+ }
1871
+ beginDeferredEmit() {
1872
+ this._deferredCnt++;
1873
+ }
1874
+ endDeferredEmit(resultingSelection = null) {
1875
+ this._deferredCnt--;
1876
+ if (this._deferredCnt === 0) {
1877
+ if (this._deferredEvent !== null) {
1878
+ this._deferredEvent.rawContentChangedEvent.resultingSelection = resultingSelection;
1879
+ const e = this._deferredEvent;
1880
+ this._deferredEvent = null;
1881
+ this._fastEmitter.fire(e);
1882
+ this._slowEmitter.fire(e);
1883
+ }
1884
+ }
1885
+ }
1886
+ fire(e) {
1887
+ if (this._deferredCnt > 0) {
1888
+ if (this._deferredEvent) {
1889
+ this._deferredEvent = this._deferredEvent.merge(e);
1890
+ }
1891
+ else {
1892
+ this._deferredEvent = e;
1893
+ }
1894
+ return;
1895
+ }
1896
+ this._fastEmitter.fire(e);
1897
+ this._slowEmitter.fire(e);
1898
+ }
1899
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/textModelPart.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { Disposable } from '../../../base/common/lifecycle.js';
6
+ export class TextModelPart extends Disposable {
7
+ constructor() {
8
+ super(...arguments);
9
+ this._isDisposed = false;
10
+ }
11
+ dispose() {
12
+ super.dispose();
13
+ this._isDisposed = true;
14
+ }
15
+ assertNotDisposed() {
16
+ if (this._isDisposed) {
17
+ throw new Error('TextModelPart is disposed!');
18
+ }
19
+ }
20
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/textModelSearch.js ADDED
@@ -0,0 +1,452 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import * as strings from '../../../base/common/strings.js';
6
+ import { getMapForWordSeparators } from '../core/wordCharacterClassifier.js';
7
+ import { Position } from '../core/position.js';
8
+ import { Range } from '../core/range.js';
9
+ import { FindMatch, SearchData } from '../model.js';
10
+ const LIMIT_FIND_COUNT = 999;
11
+ export class SearchParams {
12
+ constructor(searchString, isRegex, matchCase, wordSeparators) {
13
+ this.searchString = searchString;
14
+ this.isRegex = isRegex;
15
+ this.matchCase = matchCase;
16
+ this.wordSeparators = wordSeparators;
17
+ }
18
+ parseSearchRequest() {
19
+ if (this.searchString === '') {
20
+ return null;
21
+ }
22
+ // Try to create a RegExp out of the params
23
+ let multiline;
24
+ if (this.isRegex) {
25
+ multiline = isMultilineRegexSource(this.searchString);
26
+ }
27
+ else {
28
+ multiline = (this.searchString.indexOf('\n') >= 0);
29
+ }
30
+ let regex = null;
31
+ try {
32
+ regex = strings.createRegExp(this.searchString, this.isRegex, {
33
+ matchCase: this.matchCase,
34
+ wholeWord: false,
35
+ multiline: multiline,
36
+ global: true,
37
+ unicode: true
38
+ });
39
+ }
40
+ catch (err) {
41
+ return null;
42
+ }
43
+ if (!regex) {
44
+ return null;
45
+ }
46
+ let canUseSimpleSearch = (!this.isRegex && !multiline);
47
+ if (canUseSimpleSearch && this.searchString.toLowerCase() !== this.searchString.toUpperCase()) {
48
+ // casing might make a difference
49
+ canUseSimpleSearch = this.matchCase;
50
+ }
51
+ return new SearchData(regex, this.wordSeparators ? getMapForWordSeparators(this.wordSeparators, []) : null, canUseSimpleSearch ? this.searchString : null);
52
+ }
53
+ }
54
+ export function isMultilineRegexSource(searchString) {
55
+ if (!searchString || searchString.length === 0) {
56
+ return false;
57
+ }
58
+ for (let i = 0, len = searchString.length; i < len; i++) {
59
+ const chCode = searchString.charCodeAt(i);
60
+ if (chCode === 10 /* CharCode.LineFeed */) {
61
+ return true;
62
+ }
63
+ if (chCode === 92 /* CharCode.Backslash */) {
64
+ // move to next char
65
+ i++;
66
+ if (i >= len) {
67
+ // string ends with a \
68
+ break;
69
+ }
70
+ const nextChCode = searchString.charCodeAt(i);
71
+ if (nextChCode === 110 /* CharCode.n */ || nextChCode === 114 /* CharCode.r */ || nextChCode === 87 /* CharCode.W */) {
72
+ return true;
73
+ }
74
+ }
75
+ }
76
+ return false;
77
+ }
78
+ export function createFindMatch(range, rawMatches, captureMatches) {
79
+ if (!captureMatches) {
80
+ return new FindMatch(range, null);
81
+ }
82
+ const matches = [];
83
+ for (let i = 0, len = rawMatches.length; i < len; i++) {
84
+ matches[i] = rawMatches[i];
85
+ }
86
+ return new FindMatch(range, matches);
87
+ }
88
+ class LineFeedCounter {
89
+ constructor(text) {
90
+ const lineFeedsOffsets = [];
91
+ let lineFeedsOffsetsLen = 0;
92
+ for (let i = 0, textLen = text.length; i < textLen; i++) {
93
+ if (text.charCodeAt(i) === 10 /* CharCode.LineFeed */) {
94
+ lineFeedsOffsets[lineFeedsOffsetsLen++] = i;
95
+ }
96
+ }
97
+ this._lineFeedsOffsets = lineFeedsOffsets;
98
+ }
99
+ findLineFeedCountBeforeOffset(offset) {
100
+ const lineFeedsOffsets = this._lineFeedsOffsets;
101
+ let min = 0;
102
+ let max = lineFeedsOffsets.length - 1;
103
+ if (max === -1) {
104
+ // no line feeds
105
+ return 0;
106
+ }
107
+ if (offset <= lineFeedsOffsets[0]) {
108
+ // before first line feed
109
+ return 0;
110
+ }
111
+ while (min < max) {
112
+ const mid = min + ((max - min) / 2 >> 0);
113
+ if (lineFeedsOffsets[mid] >= offset) {
114
+ max = mid - 1;
115
+ }
116
+ else {
117
+ if (lineFeedsOffsets[mid + 1] >= offset) {
118
+ // bingo!
119
+ min = mid;
120
+ max = mid;
121
+ }
122
+ else {
123
+ min = mid + 1;
124
+ }
125
+ }
126
+ }
127
+ return min + 1;
128
+ }
129
+ }
130
+ export class TextModelSearch {
131
+ static findMatches(model, searchParams, searchRange, captureMatches, limitResultCount) {
132
+ const searchData = searchParams.parseSearchRequest();
133
+ if (!searchData) {
134
+ return [];
135
+ }
136
+ if (searchData.regex.multiline) {
137
+ return this._doFindMatchesMultiline(model, searchRange, new Searcher(searchData.wordSeparators, searchData.regex), captureMatches, limitResultCount);
138
+ }
139
+ return this._doFindMatchesLineByLine(model, searchRange, searchData, captureMatches, limitResultCount);
140
+ }
141
+ /**
142
+ * Multiline search always executes on the lines concatenated with \n.
143
+ * We must therefore compensate for the count of \n in case the model is CRLF
144
+ */
145
+ static _getMultilineMatchRange(model, deltaOffset, text, lfCounter, matchIndex, match0) {
146
+ let startOffset;
147
+ let lineFeedCountBeforeMatch = 0;
148
+ if (lfCounter) {
149
+ lineFeedCountBeforeMatch = lfCounter.findLineFeedCountBeforeOffset(matchIndex);
150
+ startOffset = deltaOffset + matchIndex + lineFeedCountBeforeMatch /* add as many \r as there were \n */;
151
+ }
152
+ else {
153
+ startOffset = deltaOffset + matchIndex;
154
+ }
155
+ let endOffset;
156
+ if (lfCounter) {
157
+ const lineFeedCountBeforeEndOfMatch = lfCounter.findLineFeedCountBeforeOffset(matchIndex + match0.length);
158
+ const lineFeedCountInMatch = lineFeedCountBeforeEndOfMatch - lineFeedCountBeforeMatch;
159
+ endOffset = startOffset + match0.length + lineFeedCountInMatch /* add as many \r as there were \n */;
160
+ }
161
+ else {
162
+ endOffset = startOffset + match0.length;
163
+ }
164
+ const startPosition = model.getPositionAt(startOffset);
165
+ const endPosition = model.getPositionAt(endOffset);
166
+ return new Range(startPosition.lineNumber, startPosition.column, endPosition.lineNumber, endPosition.column);
167
+ }
168
+ static _doFindMatchesMultiline(model, searchRange, searcher, captureMatches, limitResultCount) {
169
+ const deltaOffset = model.getOffsetAt(searchRange.getStartPosition());
170
+ // We always execute multiline search over the lines joined with \n
171
+ // This makes it that \n will match the EOL for both CRLF and LF models
172
+ // We compensate for offset errors in `_getMultilineMatchRange`
173
+ const text = model.getValueInRange(searchRange, 1 /* EndOfLinePreference.LF */);
174
+ const lfCounter = (model.getEOL() === '\r\n' ? new LineFeedCounter(text) : null);
175
+ const result = [];
176
+ let counter = 0;
177
+ let m;
178
+ searcher.reset(0);
179
+ while ((m = searcher.next(text))) {
180
+ result[counter++] = createFindMatch(this._getMultilineMatchRange(model, deltaOffset, text, lfCounter, m.index, m[0]), m, captureMatches);
181
+ if (counter >= limitResultCount) {
182
+ return result;
183
+ }
184
+ }
185
+ return result;
186
+ }
187
+ static _doFindMatchesLineByLine(model, searchRange, searchData, captureMatches, limitResultCount) {
188
+ const result = [];
189
+ let resultLen = 0;
190
+ // Early case for a search range that starts & stops on the same line number
191
+ if (searchRange.startLineNumber === searchRange.endLineNumber) {
192
+ const text = model.getLineContent(searchRange.startLineNumber).substring(searchRange.startColumn - 1, searchRange.endColumn - 1);
193
+ resultLen = this._findMatchesInLine(searchData, text, searchRange.startLineNumber, searchRange.startColumn - 1, resultLen, result, captureMatches, limitResultCount);
194
+ return result;
195
+ }
196
+ // Collect results from first line
197
+ const text = model.getLineContent(searchRange.startLineNumber).substring(searchRange.startColumn - 1);
198
+ resultLen = this._findMatchesInLine(searchData, text, searchRange.startLineNumber, searchRange.startColumn - 1, resultLen, result, captureMatches, limitResultCount);
199
+ // Collect results from middle lines
200
+ for (let lineNumber = searchRange.startLineNumber + 1; lineNumber < searchRange.endLineNumber && resultLen < limitResultCount; lineNumber++) {
201
+ resultLen = this._findMatchesInLine(searchData, model.getLineContent(lineNumber), lineNumber, 0, resultLen, result, captureMatches, limitResultCount);
202
+ }
203
+ // Collect results from last line
204
+ if (resultLen < limitResultCount) {
205
+ const text = model.getLineContent(searchRange.endLineNumber).substring(0, searchRange.endColumn - 1);
206
+ resultLen = this._findMatchesInLine(searchData, text, searchRange.endLineNumber, 0, resultLen, result, captureMatches, limitResultCount);
207
+ }
208
+ return result;
209
+ }
210
+ static _findMatchesInLine(searchData, text, lineNumber, deltaOffset, resultLen, result, captureMatches, limitResultCount) {
211
+ const wordSeparators = searchData.wordSeparators;
212
+ if (!captureMatches && searchData.simpleSearch) {
213
+ const searchString = searchData.simpleSearch;
214
+ const searchStringLen = searchString.length;
215
+ const textLength = text.length;
216
+ let lastMatchIndex = -searchStringLen;
217
+ while ((lastMatchIndex = text.indexOf(searchString, lastMatchIndex + searchStringLen)) !== -1) {
218
+ if (!wordSeparators || isValidMatch(wordSeparators, text, textLength, lastMatchIndex, searchStringLen)) {
219
+ result[resultLen++] = new FindMatch(new Range(lineNumber, lastMatchIndex + 1 + deltaOffset, lineNumber, lastMatchIndex + 1 + searchStringLen + deltaOffset), null);
220
+ if (resultLen >= limitResultCount) {
221
+ return resultLen;
222
+ }
223
+ }
224
+ }
225
+ return resultLen;
226
+ }
227
+ const searcher = new Searcher(searchData.wordSeparators, searchData.regex);
228
+ let m;
229
+ // Reset regex to search from the beginning
230
+ searcher.reset(0);
231
+ do {
232
+ m = searcher.next(text);
233
+ if (m) {
234
+ result[resultLen++] = createFindMatch(new Range(lineNumber, m.index + 1 + deltaOffset, lineNumber, m.index + 1 + m[0].length + deltaOffset), m, captureMatches);
235
+ if (resultLen >= limitResultCount) {
236
+ return resultLen;
237
+ }
238
+ }
239
+ } while (m);
240
+ return resultLen;
241
+ }
242
+ static findNextMatch(model, searchParams, searchStart, captureMatches) {
243
+ const searchData = searchParams.parseSearchRequest();
244
+ if (!searchData) {
245
+ return null;
246
+ }
247
+ const searcher = new Searcher(searchData.wordSeparators, searchData.regex);
248
+ if (searchData.regex.multiline) {
249
+ return this._doFindNextMatchMultiline(model, searchStart, searcher, captureMatches);
250
+ }
251
+ return this._doFindNextMatchLineByLine(model, searchStart, searcher, captureMatches);
252
+ }
253
+ static _doFindNextMatchMultiline(model, searchStart, searcher, captureMatches) {
254
+ const searchTextStart = new Position(searchStart.lineNumber, 1);
255
+ const deltaOffset = model.getOffsetAt(searchTextStart);
256
+ const lineCount = model.getLineCount();
257
+ // We always execute multiline search over the lines joined with \n
258
+ // This makes it that \n will match the EOL for both CRLF and LF models
259
+ // We compensate for offset errors in `_getMultilineMatchRange`
260
+ const text = model.getValueInRange(new Range(searchTextStart.lineNumber, searchTextStart.column, lineCount, model.getLineMaxColumn(lineCount)), 1 /* EndOfLinePreference.LF */);
261
+ const lfCounter = (model.getEOL() === '\r\n' ? new LineFeedCounter(text) : null);
262
+ searcher.reset(searchStart.column - 1);
263
+ const m = searcher.next(text);
264
+ if (m) {
265
+ return createFindMatch(this._getMultilineMatchRange(model, deltaOffset, text, lfCounter, m.index, m[0]), m, captureMatches);
266
+ }
267
+ if (searchStart.lineNumber !== 1 || searchStart.column !== 1) {
268
+ // Try again from the top
269
+ return this._doFindNextMatchMultiline(model, new Position(1, 1), searcher, captureMatches);
270
+ }
271
+ return null;
272
+ }
273
+ static _doFindNextMatchLineByLine(model, searchStart, searcher, captureMatches) {
274
+ const lineCount = model.getLineCount();
275
+ const startLineNumber = searchStart.lineNumber;
276
+ // Look in first line
277
+ const text = model.getLineContent(startLineNumber);
278
+ const r = this._findFirstMatchInLine(searcher, text, startLineNumber, searchStart.column, captureMatches);
279
+ if (r) {
280
+ return r;
281
+ }
282
+ for (let i = 1; i <= lineCount; i++) {
283
+ const lineIndex = (startLineNumber + i - 1) % lineCount;
284
+ const text = model.getLineContent(lineIndex + 1);
285
+ const r = this._findFirstMatchInLine(searcher, text, lineIndex + 1, 1, captureMatches);
286
+ if (r) {
287
+ return r;
288
+ }
289
+ }
290
+ return null;
291
+ }
292
+ static _findFirstMatchInLine(searcher, text, lineNumber, fromColumn, captureMatches) {
293
+ // Set regex to search from column
294
+ searcher.reset(fromColumn - 1);
295
+ const m = searcher.next(text);
296
+ if (m) {
297
+ return createFindMatch(new Range(lineNumber, m.index + 1, lineNumber, m.index + 1 + m[0].length), m, captureMatches);
298
+ }
299
+ return null;
300
+ }
301
+ static findPreviousMatch(model, searchParams, searchStart, captureMatches) {
302
+ const searchData = searchParams.parseSearchRequest();
303
+ if (!searchData) {
304
+ return null;
305
+ }
306
+ const searcher = new Searcher(searchData.wordSeparators, searchData.regex);
307
+ if (searchData.regex.multiline) {
308
+ return this._doFindPreviousMatchMultiline(model, searchStart, searcher, captureMatches);
309
+ }
310
+ return this._doFindPreviousMatchLineByLine(model, searchStart, searcher, captureMatches);
311
+ }
312
+ static _doFindPreviousMatchMultiline(model, searchStart, searcher, captureMatches) {
313
+ const matches = this._doFindMatchesMultiline(model, new Range(1, 1, searchStart.lineNumber, searchStart.column), searcher, captureMatches, 10 * LIMIT_FIND_COUNT);
314
+ if (matches.length > 0) {
315
+ return matches[matches.length - 1];
316
+ }
317
+ const lineCount = model.getLineCount();
318
+ if (searchStart.lineNumber !== lineCount || searchStart.column !== model.getLineMaxColumn(lineCount)) {
319
+ // Try again with all content
320
+ return this._doFindPreviousMatchMultiline(model, new Position(lineCount, model.getLineMaxColumn(lineCount)), searcher, captureMatches);
321
+ }
322
+ return null;
323
+ }
324
+ static _doFindPreviousMatchLineByLine(model, searchStart, searcher, captureMatches) {
325
+ const lineCount = model.getLineCount();
326
+ const startLineNumber = searchStart.lineNumber;
327
+ // Look in first line
328
+ const text = model.getLineContent(startLineNumber).substring(0, searchStart.column - 1);
329
+ const r = this._findLastMatchInLine(searcher, text, startLineNumber, captureMatches);
330
+ if (r) {
331
+ return r;
332
+ }
333
+ for (let i = 1; i <= lineCount; i++) {
334
+ const lineIndex = (lineCount + startLineNumber - i - 1) % lineCount;
335
+ const text = model.getLineContent(lineIndex + 1);
336
+ const r = this._findLastMatchInLine(searcher, text, lineIndex + 1, captureMatches);
337
+ if (r) {
338
+ return r;
339
+ }
340
+ }
341
+ return null;
342
+ }
343
+ static _findLastMatchInLine(searcher, text, lineNumber, captureMatches) {
344
+ let bestResult = null;
345
+ let m;
346
+ searcher.reset(0);
347
+ while ((m = searcher.next(text))) {
348
+ bestResult = createFindMatch(new Range(lineNumber, m.index + 1, lineNumber, m.index + 1 + m[0].length), m, captureMatches);
349
+ }
350
+ return bestResult;
351
+ }
352
+ }
353
+ function leftIsWordBounday(wordSeparators, text, textLength, matchStartIndex, matchLength) {
354
+ if (matchStartIndex === 0) {
355
+ // Match starts at start of string
356
+ return true;
357
+ }
358
+ const charBefore = text.charCodeAt(matchStartIndex - 1);
359
+ if (wordSeparators.get(charBefore) !== 0 /* WordCharacterClass.Regular */) {
360
+ // The character before the match is a word separator
361
+ return true;
362
+ }
363
+ if (charBefore === 13 /* CharCode.CarriageReturn */ || charBefore === 10 /* CharCode.LineFeed */) {
364
+ // The character before the match is line break or carriage return.
365
+ return true;
366
+ }
367
+ if (matchLength > 0) {
368
+ const firstCharInMatch = text.charCodeAt(matchStartIndex);
369
+ if (wordSeparators.get(firstCharInMatch) !== 0 /* WordCharacterClass.Regular */) {
370
+ // The first character inside the match is a word separator
371
+ return true;
372
+ }
373
+ }
374
+ return false;
375
+ }
376
+ function rightIsWordBounday(wordSeparators, text, textLength, matchStartIndex, matchLength) {
377
+ if (matchStartIndex + matchLength === textLength) {
378
+ // Match ends at end of string
379
+ return true;
380
+ }
381
+ const charAfter = text.charCodeAt(matchStartIndex + matchLength);
382
+ if (wordSeparators.get(charAfter) !== 0 /* WordCharacterClass.Regular */) {
383
+ // The character after the match is a word separator
384
+ return true;
385
+ }
386
+ if (charAfter === 13 /* CharCode.CarriageReturn */ || charAfter === 10 /* CharCode.LineFeed */) {
387
+ // The character after the match is line break or carriage return.
388
+ return true;
389
+ }
390
+ if (matchLength > 0) {
391
+ const lastCharInMatch = text.charCodeAt(matchStartIndex + matchLength - 1);
392
+ if (wordSeparators.get(lastCharInMatch) !== 0 /* WordCharacterClass.Regular */) {
393
+ // The last character in the match is a word separator
394
+ return true;
395
+ }
396
+ }
397
+ return false;
398
+ }
399
+ export function isValidMatch(wordSeparators, text, textLength, matchStartIndex, matchLength) {
400
+ return (leftIsWordBounday(wordSeparators, text, textLength, matchStartIndex, matchLength)
401
+ && rightIsWordBounday(wordSeparators, text, textLength, matchStartIndex, matchLength));
402
+ }
403
+ export class Searcher {
404
+ constructor(wordSeparators, searchRegex) {
405
+ this._wordSeparators = wordSeparators;
406
+ this._searchRegex = searchRegex;
407
+ this._prevMatchStartIndex = -1;
408
+ this._prevMatchLength = 0;
409
+ }
410
+ reset(lastIndex) {
411
+ this._searchRegex.lastIndex = lastIndex;
412
+ this._prevMatchStartIndex = -1;
413
+ this._prevMatchLength = 0;
414
+ }
415
+ next(text) {
416
+ const textLength = text.length;
417
+ let m;
418
+ do {
419
+ if (this._prevMatchStartIndex + this._prevMatchLength === textLength) {
420
+ // Reached the end of the line
421
+ return null;
422
+ }
423
+ m = this._searchRegex.exec(text);
424
+ if (!m) {
425
+ return null;
426
+ }
427
+ const matchStartIndex = m.index;
428
+ const matchLength = m[0].length;
429
+ if (matchStartIndex === this._prevMatchStartIndex && matchLength === this._prevMatchLength) {
430
+ if (matchLength === 0) {
431
+ // the search result is an empty string and won't advance `regex.lastIndex`, so `regex.exec` will stuck here
432
+ // we attempt to recover from that by advancing by two if surrogate pair found and by one otherwise
433
+ if (strings.getNextCodePoint(text, textLength, this._searchRegex.lastIndex) > 0xFFFF) {
434
+ this._searchRegex.lastIndex += 2;
435
+ }
436
+ else {
437
+ this._searchRegex.lastIndex += 1;
438
+ }
439
+ continue;
440
+ }
441
+ // Exit early if the regex matches the same range twice
442
+ return null;
443
+ }
444
+ this._prevMatchStartIndex = matchStartIndex;
445
+ this._prevMatchLength = matchLength;
446
+ if (!this._wordSeparators || isValidMatch(this._wordSeparators, text, textLength, matchStartIndex, matchLength)) {
447
+ return m;
448
+ }
449
+ } while (m);
450
+ return null;
451
+ }
452
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/textModelText.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { AbstractText } from '../core/textEdit.js';
6
+ import { TextLength } from '../core/textLength.js';
7
+ export class TextModelText extends AbstractText {
8
+ constructor(_textModel) {
9
+ super();
10
+ this._textModel = _textModel;
11
+ }
12
+ getValueOfRange(range) {
13
+ return this._textModel.getValueInRange(range);
14
+ }
15
+ get length() {
16
+ const lastLineNumber = this._textModel.getLineCount();
17
+ const lastLineLen = this._textModel.getLineLength(lastLineNumber);
18
+ return new TextLength(lastLineNumber - 1, lastLineLen);
19
+ }
20
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/textModelTokens.js ADDED
@@ -0,0 +1,429 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { runWhenGlobalIdle } from '../../../base/common/async.js';
6
+ import { BugIndicatingError, onUnexpectedError } from '../../../base/common/errors.js';
7
+ import { setTimeout0 } from '../../../base/common/platform.js';
8
+ import { StopWatch } from '../../../base/common/stopwatch.js';
9
+ import { countEOL } from '../core/eolCounter.js';
10
+ import { LineRange } from '../core/lineRange.js';
11
+ import { OffsetRange } from '../core/offsetRange.js';
12
+ import { nullTokenizeEncoded } from '../languages/nullTokenize.js';
13
+ import { FixedArray } from './fixedArray.js';
14
+ import { ContiguousMultilineTokensBuilder } from '../tokens/contiguousMultilineTokensBuilder.js';
15
+ import { LineTokens } from '../tokens/lineTokens.js';
16
+ export class TokenizerWithStateStore {
17
+ constructor(lineCount, tokenizationSupport) {
18
+ this.tokenizationSupport = tokenizationSupport;
19
+ this.initialState = this.tokenizationSupport.getInitialState();
20
+ this.store = new TrackingTokenizationStateStore(lineCount);
21
+ }
22
+ getStartState(lineNumber) {
23
+ return this.store.getStartState(lineNumber, this.initialState);
24
+ }
25
+ getFirstInvalidLine() {
26
+ return this.store.getFirstInvalidLine(this.initialState);
27
+ }
28
+ }
29
+ export class TokenizerWithStateStoreAndTextModel extends TokenizerWithStateStore {
30
+ constructor(lineCount, tokenizationSupport, _textModel, _languageIdCodec) {
31
+ super(lineCount, tokenizationSupport);
32
+ this._textModel = _textModel;
33
+ this._languageIdCodec = _languageIdCodec;
34
+ }
35
+ updateTokensUntilLine(builder, lineNumber) {
36
+ const languageId = this._textModel.getLanguageId();
37
+ while (true) {
38
+ const lineToTokenize = this.getFirstInvalidLine();
39
+ if (!lineToTokenize || lineToTokenize.lineNumber > lineNumber) {
40
+ break;
41
+ }
42
+ const text = this._textModel.getLineContent(lineToTokenize.lineNumber);
43
+ const r = safeTokenize(this._languageIdCodec, languageId, this.tokenizationSupport, text, true, lineToTokenize.startState);
44
+ builder.add(lineToTokenize.lineNumber, r.tokens);
45
+ this.store.setEndState(lineToTokenize.lineNumber, r.endState);
46
+ }
47
+ }
48
+ /** assumes state is up to date */
49
+ getTokenTypeIfInsertingCharacter(position, character) {
50
+ // TODO@hediet: use tokenizeLineWithEdit
51
+ const lineStartState = this.getStartState(position.lineNumber);
52
+ if (!lineStartState) {
53
+ return 0 /* StandardTokenType.Other */;
54
+ }
55
+ const languageId = this._textModel.getLanguageId();
56
+ const lineContent = this._textModel.getLineContent(position.lineNumber);
57
+ // Create the text as if `character` was inserted
58
+ const text = (lineContent.substring(0, position.column - 1)
59
+ + character
60
+ + lineContent.substring(position.column - 1));
61
+ const r = safeTokenize(this._languageIdCodec, languageId, this.tokenizationSupport, text, true, lineStartState);
62
+ const lineTokens = new LineTokens(r.tokens, text, this._languageIdCodec);
63
+ if (lineTokens.getCount() === 0) {
64
+ return 0 /* StandardTokenType.Other */;
65
+ }
66
+ const tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
67
+ return lineTokens.getStandardTokenType(tokenIndex);
68
+ }
69
+ /** assumes state is up to date */
70
+ tokenizeLineWithEdit(position, length, newText) {
71
+ const lineNumber = position.lineNumber;
72
+ const column = position.column;
73
+ const lineStartState = this.getStartState(lineNumber);
74
+ if (!lineStartState) {
75
+ return null;
76
+ }
77
+ const curLineContent = this._textModel.getLineContent(lineNumber);
78
+ const newLineContent = curLineContent.substring(0, column - 1)
79
+ + newText + curLineContent.substring(column - 1 + length);
80
+ const languageId = this._textModel.getLanguageIdAtPosition(lineNumber, 0);
81
+ const result = safeTokenize(this._languageIdCodec, languageId, this.tokenizationSupport, newLineContent, true, lineStartState);
82
+ const lineTokens = new LineTokens(result.tokens, newLineContent, this._languageIdCodec);
83
+ return lineTokens;
84
+ }
85
+ hasAccurateTokensForLine(lineNumber) {
86
+ const firstInvalidLineNumber = this.store.getFirstInvalidEndStateLineNumberOrMax();
87
+ return (lineNumber < firstInvalidLineNumber);
88
+ }
89
+ isCheapToTokenize(lineNumber) {
90
+ const firstInvalidLineNumber = this.store.getFirstInvalidEndStateLineNumberOrMax();
91
+ if (lineNumber < firstInvalidLineNumber) {
92
+ return true;
93
+ }
94
+ if (lineNumber === firstInvalidLineNumber
95
+ && this._textModel.getLineLength(lineNumber) < 2048 /* Constants.CHEAP_TOKENIZATION_LENGTH_LIMIT */) {
96
+ return true;
97
+ }
98
+ return false;
99
+ }
100
+ /**
101
+ * The result is not cached.
102
+ */
103
+ tokenizeHeuristically(builder, startLineNumber, endLineNumber) {
104
+ if (endLineNumber <= this.store.getFirstInvalidEndStateLineNumberOrMax()) {
105
+ // nothing to do
106
+ return { heuristicTokens: false };
107
+ }
108
+ if (startLineNumber <= this.store.getFirstInvalidEndStateLineNumberOrMax()) {
109
+ // tokenization has reached the viewport start...
110
+ this.updateTokensUntilLine(builder, endLineNumber);
111
+ return { heuristicTokens: false };
112
+ }
113
+ let state = this.guessStartState(startLineNumber);
114
+ const languageId = this._textModel.getLanguageId();
115
+ for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
116
+ const text = this._textModel.getLineContent(lineNumber);
117
+ const r = safeTokenize(this._languageIdCodec, languageId, this.tokenizationSupport, text, true, state);
118
+ builder.add(lineNumber, r.tokens);
119
+ state = r.endState;
120
+ }
121
+ return { heuristicTokens: true };
122
+ }
123
+ guessStartState(lineNumber) {
124
+ let nonWhitespaceColumn = this._textModel.getLineFirstNonWhitespaceColumn(lineNumber);
125
+ const likelyRelevantLines = [];
126
+ let initialState = null;
127
+ for (let i = lineNumber - 1; nonWhitespaceColumn > 1 && i >= 1; i--) {
128
+ const newNonWhitespaceIndex = this._textModel.getLineFirstNonWhitespaceColumn(i);
129
+ // Ignore lines full of whitespace
130
+ if (newNonWhitespaceIndex === 0) {
131
+ continue;
132
+ }
133
+ if (newNonWhitespaceIndex < nonWhitespaceColumn) {
134
+ likelyRelevantLines.push(this._textModel.getLineContent(i));
135
+ nonWhitespaceColumn = newNonWhitespaceIndex;
136
+ initialState = this.getStartState(i);
137
+ if (initialState) {
138
+ break;
139
+ }
140
+ }
141
+ }
142
+ if (!initialState) {
143
+ initialState = this.tokenizationSupport.getInitialState();
144
+ }
145
+ likelyRelevantLines.reverse();
146
+ const languageId = this._textModel.getLanguageId();
147
+ let state = initialState;
148
+ for (const line of likelyRelevantLines) {
149
+ const r = safeTokenize(this._languageIdCodec, languageId, this.tokenizationSupport, line, false, state);
150
+ state = r.endState;
151
+ }
152
+ return state;
153
+ }
154
+ }
155
+ /**
156
+ * **Invariant:**
157
+ * If the text model is retokenized from line 1 to {@link getFirstInvalidEndStateLineNumber}() - 1,
158
+ * then the recomputed end state for line l will be equal to {@link getEndState}(l).
159
+ */
160
+ export class TrackingTokenizationStateStore {
161
+ constructor(lineCount) {
162
+ this.lineCount = lineCount;
163
+ this._tokenizationStateStore = new TokenizationStateStore();
164
+ this._invalidEndStatesLineNumbers = new RangePriorityQueueImpl();
165
+ this._invalidEndStatesLineNumbers.addRange(new OffsetRange(1, lineCount + 1));
166
+ }
167
+ getEndState(lineNumber) {
168
+ return this._tokenizationStateStore.getEndState(lineNumber);
169
+ }
170
+ /**
171
+ * @returns if the end state has changed.
172
+ */
173
+ setEndState(lineNumber, state) {
174
+ if (!state) {
175
+ throw new BugIndicatingError('Cannot set null/undefined state');
176
+ }
177
+ this._invalidEndStatesLineNumbers.delete(lineNumber);
178
+ const r = this._tokenizationStateStore.setEndState(lineNumber, state);
179
+ if (r && lineNumber < this.lineCount) {
180
+ // because the state changed, we cannot trust the next state anymore and have to invalidate it.
181
+ this._invalidEndStatesLineNumbers.addRange(new OffsetRange(lineNumber + 1, lineNumber + 2));
182
+ }
183
+ return r;
184
+ }
185
+ acceptChange(range, newLineCount) {
186
+ this.lineCount += newLineCount - range.length;
187
+ this._tokenizationStateStore.acceptChange(range, newLineCount);
188
+ this._invalidEndStatesLineNumbers.addRangeAndResize(new OffsetRange(range.startLineNumber, range.endLineNumberExclusive), newLineCount);
189
+ }
190
+ acceptChanges(changes) {
191
+ for (const c of changes) {
192
+ const [eolCount] = countEOL(c.text);
193
+ this.acceptChange(new LineRange(c.range.startLineNumber, c.range.endLineNumber + 1), eolCount + 1);
194
+ }
195
+ }
196
+ invalidateEndStateRange(range) {
197
+ this._invalidEndStatesLineNumbers.addRange(new OffsetRange(range.startLineNumber, range.endLineNumberExclusive));
198
+ }
199
+ getFirstInvalidEndStateLineNumber() { return this._invalidEndStatesLineNumbers.min; }
200
+ getFirstInvalidEndStateLineNumberOrMax() {
201
+ return this.getFirstInvalidEndStateLineNumber() || Number.MAX_SAFE_INTEGER;
202
+ }
203
+ allStatesValid() { return this._invalidEndStatesLineNumbers.min === null; }
204
+ getStartState(lineNumber, initialState) {
205
+ if (lineNumber === 1) {
206
+ return initialState;
207
+ }
208
+ return this.getEndState(lineNumber - 1);
209
+ }
210
+ getFirstInvalidLine(initialState) {
211
+ const lineNumber = this.getFirstInvalidEndStateLineNumber();
212
+ if (lineNumber === null) {
213
+ return null;
214
+ }
215
+ const startState = this.getStartState(lineNumber, initialState);
216
+ if (!startState) {
217
+ throw new BugIndicatingError('Start state must be defined');
218
+ }
219
+ return { lineNumber, startState };
220
+ }
221
+ }
222
+ export class TokenizationStateStore {
223
+ constructor() {
224
+ this._lineEndStates = new FixedArray(null);
225
+ }
226
+ getEndState(lineNumber) {
227
+ return this._lineEndStates.get(lineNumber);
228
+ }
229
+ setEndState(lineNumber, state) {
230
+ const oldState = this._lineEndStates.get(lineNumber);
231
+ if (oldState && oldState.equals(state)) {
232
+ return false;
233
+ }
234
+ this._lineEndStates.set(lineNumber, state);
235
+ return true;
236
+ }
237
+ acceptChange(range, newLineCount) {
238
+ let length = range.length;
239
+ if (newLineCount > 0 && length > 0) {
240
+ // Keep the last state, even though it is unrelated.
241
+ // But if the new state happens to agree with this last state, then we know we can stop tokenizing.
242
+ length--;
243
+ newLineCount--;
244
+ }
245
+ this._lineEndStates.replace(range.startLineNumber, length, newLineCount);
246
+ }
247
+ }
248
+ export class RangePriorityQueueImpl {
249
+ constructor() {
250
+ this._ranges = [];
251
+ }
252
+ get min() {
253
+ if (this._ranges.length === 0) {
254
+ return null;
255
+ }
256
+ return this._ranges[0].start;
257
+ }
258
+ delete(value) {
259
+ const idx = this._ranges.findIndex(r => r.contains(value));
260
+ if (idx !== -1) {
261
+ const range = this._ranges[idx];
262
+ if (range.start === value) {
263
+ if (range.endExclusive === value + 1) {
264
+ this._ranges.splice(idx, 1);
265
+ }
266
+ else {
267
+ this._ranges[idx] = new OffsetRange(value + 1, range.endExclusive);
268
+ }
269
+ }
270
+ else {
271
+ if (range.endExclusive === value + 1) {
272
+ this._ranges[idx] = new OffsetRange(range.start, value);
273
+ }
274
+ else {
275
+ this._ranges.splice(idx, 1, new OffsetRange(range.start, value), new OffsetRange(value + 1, range.endExclusive));
276
+ }
277
+ }
278
+ }
279
+ }
280
+ addRange(range) {
281
+ OffsetRange.addRange(range, this._ranges);
282
+ }
283
+ addRangeAndResize(range, newLength) {
284
+ let idxFirstMightBeIntersecting = 0;
285
+ while (!(idxFirstMightBeIntersecting >= this._ranges.length || range.start <= this._ranges[idxFirstMightBeIntersecting].endExclusive)) {
286
+ idxFirstMightBeIntersecting++;
287
+ }
288
+ let idxFirstIsAfter = idxFirstMightBeIntersecting;
289
+ while (!(idxFirstIsAfter >= this._ranges.length || range.endExclusive < this._ranges[idxFirstIsAfter].start)) {
290
+ idxFirstIsAfter++;
291
+ }
292
+ const delta = newLength - range.length;
293
+ for (let i = idxFirstIsAfter; i < this._ranges.length; i++) {
294
+ this._ranges[i] = this._ranges[i].delta(delta);
295
+ }
296
+ if (idxFirstMightBeIntersecting === idxFirstIsAfter) {
297
+ const newRange = new OffsetRange(range.start, range.start + newLength);
298
+ if (!newRange.isEmpty) {
299
+ this._ranges.splice(idxFirstMightBeIntersecting, 0, newRange);
300
+ }
301
+ }
302
+ else {
303
+ const start = Math.min(range.start, this._ranges[idxFirstMightBeIntersecting].start);
304
+ const endEx = Math.max(range.endExclusive, this._ranges[idxFirstIsAfter - 1].endExclusive);
305
+ const newRange = new OffsetRange(start, endEx + delta);
306
+ if (!newRange.isEmpty) {
307
+ this._ranges.splice(idxFirstMightBeIntersecting, idxFirstIsAfter - idxFirstMightBeIntersecting, newRange);
308
+ }
309
+ else {
310
+ this._ranges.splice(idxFirstMightBeIntersecting, idxFirstIsAfter - idxFirstMightBeIntersecting);
311
+ }
312
+ }
313
+ }
314
+ toString() {
315
+ return this._ranges.map(r => r.toString()).join(' + ');
316
+ }
317
+ }
318
+ function safeTokenize(languageIdCodec, languageId, tokenizationSupport, text, hasEOL, state) {
319
+ let r = null;
320
+ if (tokenizationSupport) {
321
+ try {
322
+ r = tokenizationSupport.tokenizeEncoded(text, hasEOL, state.clone());
323
+ }
324
+ catch (e) {
325
+ onUnexpectedError(e);
326
+ }
327
+ }
328
+ if (!r) {
329
+ r = nullTokenizeEncoded(languageIdCodec.encodeLanguageId(languageId), state);
330
+ }
331
+ LineTokens.convertToEndOffset(r.tokens, text.length);
332
+ return r;
333
+ }
334
+ export class DefaultBackgroundTokenizer {
335
+ constructor(_tokenizerWithStateStore, _backgroundTokenStore) {
336
+ this._tokenizerWithStateStore = _tokenizerWithStateStore;
337
+ this._backgroundTokenStore = _backgroundTokenStore;
338
+ this._isDisposed = false;
339
+ this._isScheduled = false;
340
+ }
341
+ dispose() {
342
+ this._isDisposed = true;
343
+ }
344
+ handleChanges() {
345
+ this._beginBackgroundTokenization();
346
+ }
347
+ _beginBackgroundTokenization() {
348
+ if (this._isScheduled || !this._tokenizerWithStateStore._textModel.isAttachedToEditor() || !this._hasLinesToTokenize()) {
349
+ return;
350
+ }
351
+ this._isScheduled = true;
352
+ runWhenGlobalIdle((deadline) => {
353
+ this._isScheduled = false;
354
+ this._backgroundTokenizeWithDeadline(deadline);
355
+ });
356
+ }
357
+ /**
358
+ * Tokenize until the deadline occurs, but try to yield every 1-2ms.
359
+ */
360
+ _backgroundTokenizeWithDeadline(deadline) {
361
+ // Read the time remaining from the `deadline` immediately because it is unclear
362
+ // if the `deadline` object will be valid after execution leaves this function.
363
+ const endTime = Date.now() + deadline.timeRemaining();
364
+ const execute = () => {
365
+ if (this._isDisposed || !this._tokenizerWithStateStore._textModel.isAttachedToEditor() || !this._hasLinesToTokenize()) {
366
+ // disposed in the meantime or detached or finished
367
+ return;
368
+ }
369
+ this._backgroundTokenizeForAtLeast1ms();
370
+ if (Date.now() < endTime) {
371
+ // There is still time before reaching the deadline, so yield to the browser and then
372
+ // continue execution
373
+ setTimeout0(execute);
374
+ }
375
+ else {
376
+ // The deadline has been reached, so schedule a new idle callback if necessary
377
+ this._beginBackgroundTokenization();
378
+ }
379
+ };
380
+ execute();
381
+ }
382
+ /**
383
+ * Tokenize for at least 1ms.
384
+ */
385
+ _backgroundTokenizeForAtLeast1ms() {
386
+ const lineCount = this._tokenizerWithStateStore._textModel.getLineCount();
387
+ const builder = new ContiguousMultilineTokensBuilder();
388
+ const sw = StopWatch.create(false);
389
+ do {
390
+ if (sw.elapsed() > 1) {
391
+ // the comparison is intentionally > 1 and not >= 1 to ensure that
392
+ // a full millisecond has elapsed, given how microseconds are rounded
393
+ // to milliseconds
394
+ break;
395
+ }
396
+ const tokenizedLineNumber = this._tokenizeOneInvalidLine(builder);
397
+ if (tokenizedLineNumber >= lineCount) {
398
+ break;
399
+ }
400
+ } while (this._hasLinesToTokenize());
401
+ this._backgroundTokenStore.setTokens(builder.finalize());
402
+ this.checkFinished();
403
+ }
404
+ _hasLinesToTokenize() {
405
+ if (!this._tokenizerWithStateStore) {
406
+ return false;
407
+ }
408
+ return !this._tokenizerWithStateStore.store.allStatesValid();
409
+ }
410
+ _tokenizeOneInvalidLine(builder) {
411
+ const firstInvalidLine = this._tokenizerWithStateStore?.getFirstInvalidLine();
412
+ if (!firstInvalidLine) {
413
+ return this._tokenizerWithStateStore._textModel.getLineCount() + 1;
414
+ }
415
+ this._tokenizerWithStateStore.updateTokensUntilLine(builder, firstInvalidLine.lineNumber);
416
+ return firstInvalidLine.lineNumber;
417
+ }
418
+ checkFinished() {
419
+ if (this._isDisposed) {
420
+ return;
421
+ }
422
+ if (this._tokenizerWithStateStore.store.allStatesValid()) {
423
+ this._backgroundTokenStore.backgroundTokenizationFinished();
424
+ }
425
+ }
426
+ requestTokens(startLineNumber, endLineNumberExclusive) {
427
+ this._tokenizerWithStateStore.store.invalidateEndStateRange(new LineRange(startLineNumber, endLineNumberExclusive));
428
+ }
429
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/tokenizationTextModelPart.js ADDED
@@ -0,0 +1,530 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
6
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
8
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var TokenizationTextModelPart_1;
15
+ import { BugIndicatingError, onUnexpectedError } from '../../../base/common/errors.js';
16
+ import { Emitter, Event } from '../../../base/common/event.js';
17
+ import { DisposableMap, DisposableStore, MutableDisposable } from '../../../base/common/lifecycle.js';
18
+ import { countEOL } from '../core/eolCounter.js';
19
+ import { LineRange } from '../core/lineRange.js';
20
+ import { Position } from '../core/position.js';
21
+ import { getWordAtText } from '../core/wordHelper.js';
22
+ import { TokenizationRegistry, TreeSitterTokenizationRegistry } from '../languages.js';
23
+ import { ILanguageService } from '../languages/language.js';
24
+ import { ILanguageConfigurationService } from '../languages/languageConfigurationRegistry.js';
25
+ import { TextModelPart } from './textModelPart.js';
26
+ import { DefaultBackgroundTokenizer, TokenizerWithStateStoreAndTextModel, TrackingTokenizationStateStore } from './textModelTokens.js';
27
+ import { AbstractTokens, AttachedViewHandler } from './tokens.js';
28
+ import { TreeSitterTokens } from './treeSitterTokens.js';
29
+ import { ITreeSitterParserService } from '../services/treeSitterParserService.js';
30
+ import { ContiguousMultilineTokensBuilder } from '../tokens/contiguousMultilineTokensBuilder.js';
31
+ import { ContiguousTokensStore } from '../tokens/contiguousTokensStore.js';
32
+ import { SparseTokensStore } from '../tokens/sparseTokensStore.js';
33
+ let TokenizationTextModelPart = TokenizationTextModelPart_1 = class TokenizationTextModelPart extends TextModelPart {
34
+ constructor(_textModel, _bracketPairsTextModelPart, _languageId, _attachedViews, _languageService, _languageConfigurationService, _treeSitterService) {
35
+ super();
36
+ this._textModel = _textModel;
37
+ this._bracketPairsTextModelPart = _bracketPairsTextModelPart;
38
+ this._languageId = _languageId;
39
+ this._attachedViews = _attachedViews;
40
+ this._languageService = _languageService;
41
+ this._languageConfigurationService = _languageConfigurationService;
42
+ this._treeSitterService = _treeSitterService;
43
+ this._semanticTokens = new SparseTokensStore(this._languageService.languageIdCodec);
44
+ this._onDidChangeLanguage = this._register(new Emitter());
45
+ this.onDidChangeLanguage = this._onDidChangeLanguage.event;
46
+ this._onDidChangeLanguageConfiguration = this._register(new Emitter());
47
+ this.onDidChangeLanguageConfiguration = this._onDidChangeLanguageConfiguration.event;
48
+ this._onDidChangeTokens = this._register(new Emitter());
49
+ this.onDidChangeTokens = this._onDidChangeTokens.event;
50
+ this._tokensDisposables = this._register(new DisposableStore());
51
+ this._register(this._languageConfigurationService.onDidChange(e => {
52
+ if (e.affects(this._languageId)) {
53
+ this._onDidChangeLanguageConfiguration.fire({});
54
+ }
55
+ }));
56
+ // We just look at registry changes to determine whether to use tree sitter.
57
+ // This means that removing a language from the setting will not cause a switch to textmate and will require a reload.
58
+ // Adding a language to the setting will not need a reload, however.
59
+ this._register(Event.filter(TreeSitterTokenizationRegistry.onDidChange, (e) => e.changedLanguages.includes(this._languageId))(() => {
60
+ this.createPreferredTokenProvider();
61
+ }));
62
+ this.createPreferredTokenProvider();
63
+ }
64
+ createGrammarTokens() {
65
+ return this._register(new GrammarTokens(this._languageService.languageIdCodec, this._textModel, () => this._languageId, this._attachedViews));
66
+ }
67
+ createTreeSitterTokens() {
68
+ return this._register(new TreeSitterTokens(this._treeSitterService, this._languageService.languageIdCodec, this._textModel, () => this._languageId));
69
+ }
70
+ createTokens(useTreeSitter) {
71
+ const needsReset = this._tokens !== undefined;
72
+ this._tokens?.dispose();
73
+ this._tokens = useTreeSitter ? this.createTreeSitterTokens() : this.createGrammarTokens();
74
+ this._tokensDisposables.clear();
75
+ this._tokensDisposables.add(this._tokens.onDidChangeTokens(e => {
76
+ this._emitModelTokensChangedEvent(e);
77
+ }));
78
+ this._tokensDisposables.add(this._tokens.onDidChangeBackgroundTokenizationState(e => {
79
+ this._bracketPairsTextModelPart.handleDidChangeBackgroundTokenizationState();
80
+ }));
81
+ if (needsReset) {
82
+ // We need to reset the tokenization, as the new token provider otherwise won't have a chance to provide tokens until some action happens in the editor.
83
+ this._tokens.resetTokenization();
84
+ }
85
+ }
86
+ createPreferredTokenProvider() {
87
+ if (TreeSitterTokenizationRegistry.get(this._languageId)) {
88
+ if (!(this._tokens instanceof TreeSitterTokens)) {
89
+ this.createTokens(true);
90
+ }
91
+ }
92
+ else {
93
+ if (!(this._tokens instanceof GrammarTokens)) {
94
+ this.createTokens(false);
95
+ }
96
+ }
97
+ }
98
+ handleLanguageConfigurationServiceChange(e) {
99
+ if (e.affects(this._languageId)) {
100
+ this._onDidChangeLanguageConfiguration.fire({});
101
+ }
102
+ }
103
+ handleDidChangeContent(e) {
104
+ if (e.isFlush) {
105
+ this._semanticTokens.flush();
106
+ }
107
+ else if (!e.isEolChange) { // We don't have to do anything on an EOL change
108
+ for (const c of e.changes) {
109
+ const [eolCount, firstLineLength, lastLineLength] = countEOL(c.text);
110
+ this._semanticTokens.acceptEdit(c.range, eolCount, firstLineLength, lastLineLength, c.text.length > 0 ? c.text.charCodeAt(0) : 0 /* CharCode.Null */);
111
+ }
112
+ }
113
+ this._tokens.handleDidChangeContent(e);
114
+ }
115
+ handleDidChangeAttached() {
116
+ this._tokens.handleDidChangeAttached();
117
+ }
118
+ /**
119
+ * Includes grammar and semantic tokens.
120
+ */
121
+ getLineTokens(lineNumber) {
122
+ this.validateLineNumber(lineNumber);
123
+ const syntacticTokens = this._tokens.getLineTokens(lineNumber);
124
+ return this._semanticTokens.addSparseTokens(lineNumber, syntacticTokens);
125
+ }
126
+ _emitModelTokensChangedEvent(e) {
127
+ if (!this._textModel._isDisposing()) {
128
+ this._bracketPairsTextModelPart.handleDidChangeTokens(e);
129
+ this._onDidChangeTokens.fire(e);
130
+ }
131
+ }
132
+ // #region Grammar Tokens
133
+ validateLineNumber(lineNumber) {
134
+ if (lineNumber < 1 || lineNumber > this._textModel.getLineCount()) {
135
+ throw new BugIndicatingError('Illegal value for lineNumber');
136
+ }
137
+ }
138
+ get hasTokens() {
139
+ return this._tokens.hasTokens;
140
+ }
141
+ resetTokenization() {
142
+ this._tokens.resetTokenization();
143
+ }
144
+ get backgroundTokenizationState() {
145
+ return this._tokens.backgroundTokenizationState;
146
+ }
147
+ forceTokenization(lineNumber) {
148
+ this.validateLineNumber(lineNumber);
149
+ this._tokens.forceTokenization(lineNumber);
150
+ }
151
+ hasAccurateTokensForLine(lineNumber) {
152
+ this.validateLineNumber(lineNumber);
153
+ return this._tokens.hasAccurateTokensForLine(lineNumber);
154
+ }
155
+ isCheapToTokenize(lineNumber) {
156
+ this.validateLineNumber(lineNumber);
157
+ return this._tokens.isCheapToTokenize(lineNumber);
158
+ }
159
+ tokenizeIfCheap(lineNumber) {
160
+ this.validateLineNumber(lineNumber);
161
+ this._tokens.tokenizeIfCheap(lineNumber);
162
+ }
163
+ getTokenTypeIfInsertingCharacter(lineNumber, column, character) {
164
+ return this._tokens.getTokenTypeIfInsertingCharacter(lineNumber, column, character);
165
+ }
166
+ tokenizeLineWithEdit(position, length, newText) {
167
+ return this._tokens.tokenizeLineWithEdit(position, length, newText);
168
+ }
169
+ // #endregion
170
+ // #region Semantic Tokens
171
+ setSemanticTokens(tokens, isComplete) {
172
+ this._semanticTokens.set(tokens, isComplete);
173
+ this._emitModelTokensChangedEvent({
174
+ semanticTokensApplied: tokens !== null,
175
+ ranges: [{ fromLineNumber: 1, toLineNumber: this._textModel.getLineCount() }],
176
+ });
177
+ }
178
+ hasCompleteSemanticTokens() {
179
+ return this._semanticTokens.isComplete();
180
+ }
181
+ hasSomeSemanticTokens() {
182
+ return !this._semanticTokens.isEmpty();
183
+ }
184
+ setPartialSemanticTokens(range, tokens) {
185
+ if (this.hasCompleteSemanticTokens()) {
186
+ return;
187
+ }
188
+ const changedRange = this._textModel.validateRange(this._semanticTokens.setPartial(range, tokens));
189
+ this._emitModelTokensChangedEvent({
190
+ semanticTokensApplied: true,
191
+ ranges: [
192
+ {
193
+ fromLineNumber: changedRange.startLineNumber,
194
+ toLineNumber: changedRange.endLineNumber,
195
+ },
196
+ ],
197
+ });
198
+ }
199
+ // #endregion
200
+ // #region Utility Methods
201
+ getWordAtPosition(_position) {
202
+ this.assertNotDisposed();
203
+ const position = this._textModel.validatePosition(_position);
204
+ const lineContent = this._textModel.getLineContent(position.lineNumber);
205
+ const lineTokens = this.getLineTokens(position.lineNumber);
206
+ const tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
207
+ // (1). First try checking right biased word
208
+ const [rbStartOffset, rbEndOffset] = TokenizationTextModelPart_1._findLanguageBoundaries(lineTokens, tokenIndex);
209
+ const rightBiasedWord = getWordAtText(position.column, this.getLanguageConfiguration(lineTokens.getLanguageId(tokenIndex)).getWordDefinition(), lineContent.substring(rbStartOffset, rbEndOffset), rbStartOffset);
210
+ // Make sure the result touches the original passed in position
211
+ if (rightBiasedWord &&
212
+ rightBiasedWord.startColumn <= _position.column &&
213
+ _position.column <= rightBiasedWord.endColumn) {
214
+ return rightBiasedWord;
215
+ }
216
+ // (2). Else, if we were at a language boundary, check the left biased word
217
+ if (tokenIndex > 0 && rbStartOffset === position.column - 1) {
218
+ // edge case, where `position` sits between two tokens belonging to two different languages
219
+ const [lbStartOffset, lbEndOffset] = TokenizationTextModelPart_1._findLanguageBoundaries(lineTokens, tokenIndex - 1);
220
+ const leftBiasedWord = getWordAtText(position.column, this.getLanguageConfiguration(lineTokens.getLanguageId(tokenIndex - 1)).getWordDefinition(), lineContent.substring(lbStartOffset, lbEndOffset), lbStartOffset);
221
+ // Make sure the result touches the original passed in position
222
+ if (leftBiasedWord &&
223
+ leftBiasedWord.startColumn <= _position.column &&
224
+ _position.column <= leftBiasedWord.endColumn) {
225
+ return leftBiasedWord;
226
+ }
227
+ }
228
+ return null;
229
+ }
230
+ getLanguageConfiguration(languageId) {
231
+ return this._languageConfigurationService.getLanguageConfiguration(languageId);
232
+ }
233
+ static _findLanguageBoundaries(lineTokens, tokenIndex) {
234
+ const languageId = lineTokens.getLanguageId(tokenIndex);
235
+ // go left until a different language is hit
236
+ let startOffset = 0;
237
+ for (let i = tokenIndex; i >= 0 && lineTokens.getLanguageId(i) === languageId; i--) {
238
+ startOffset = lineTokens.getStartOffset(i);
239
+ }
240
+ // go right until a different language is hit
241
+ let endOffset = lineTokens.getLineContent().length;
242
+ for (let i = tokenIndex, tokenCount = lineTokens.getCount(); i < tokenCount && lineTokens.getLanguageId(i) === languageId; i++) {
243
+ endOffset = lineTokens.getEndOffset(i);
244
+ }
245
+ return [startOffset, endOffset];
246
+ }
247
+ getWordUntilPosition(position) {
248
+ const wordAtPosition = this.getWordAtPosition(position);
249
+ if (!wordAtPosition) {
250
+ return { word: '', startColumn: position.column, endColumn: position.column, };
251
+ }
252
+ return {
253
+ word: wordAtPosition.word.substr(0, position.column - wordAtPosition.startColumn),
254
+ startColumn: wordAtPosition.startColumn,
255
+ endColumn: position.column,
256
+ };
257
+ }
258
+ // #endregion
259
+ // #region Language Id handling
260
+ getLanguageId() {
261
+ return this._languageId;
262
+ }
263
+ getLanguageIdAtPosition(lineNumber, column) {
264
+ const position = this._textModel.validatePosition(new Position(lineNumber, column));
265
+ const lineTokens = this.getLineTokens(position.lineNumber);
266
+ return lineTokens.getLanguageId(lineTokens.findTokenIndexAtOffset(position.column - 1));
267
+ }
268
+ setLanguageId(languageId, source = 'api') {
269
+ if (this._languageId === languageId) {
270
+ // There's nothing to do
271
+ return;
272
+ }
273
+ const e = {
274
+ oldLanguage: this._languageId,
275
+ newLanguage: languageId,
276
+ source
277
+ };
278
+ this._languageId = languageId;
279
+ this._bracketPairsTextModelPart.handleDidChangeLanguage(e);
280
+ this._tokens.resetTokenization();
281
+ this.createPreferredTokenProvider();
282
+ this._onDidChangeLanguage.fire(e);
283
+ this._onDidChangeLanguageConfiguration.fire({});
284
+ }
285
+ };
286
+ TokenizationTextModelPart = TokenizationTextModelPart_1 = __decorate([
287
+ __param(4, ILanguageService),
288
+ __param(5, ILanguageConfigurationService),
289
+ __param(6, ITreeSitterParserService)
290
+ ], TokenizationTextModelPart);
291
+ export { TokenizationTextModelPart };
292
+ class GrammarTokens extends AbstractTokens {
293
+ constructor(languageIdCodec, textModel, getLanguageId, attachedViews) {
294
+ super(languageIdCodec, textModel, getLanguageId);
295
+ this._tokenizer = null;
296
+ this._defaultBackgroundTokenizer = null;
297
+ this._backgroundTokenizer = this._register(new MutableDisposable());
298
+ this._tokens = new ContiguousTokensStore(this._languageIdCodec);
299
+ this._debugBackgroundTokenizer = this._register(new MutableDisposable());
300
+ this._attachedViewStates = this._register(new DisposableMap());
301
+ this._register(TokenizationRegistry.onDidChange((e) => {
302
+ const languageId = this.getLanguageId();
303
+ if (e.changedLanguages.indexOf(languageId) === -1) {
304
+ return;
305
+ }
306
+ this.resetTokenization();
307
+ }));
308
+ this.resetTokenization();
309
+ this._register(attachedViews.onDidChangeVisibleRanges(({ view, state }) => {
310
+ if (state) {
311
+ let existing = this._attachedViewStates.get(view);
312
+ if (!existing) {
313
+ existing = new AttachedViewHandler(() => this.refreshRanges(existing.lineRanges));
314
+ this._attachedViewStates.set(view, existing);
315
+ }
316
+ existing.handleStateChange(state);
317
+ }
318
+ else {
319
+ this._attachedViewStates.deleteAndDispose(view);
320
+ }
321
+ }));
322
+ }
323
+ resetTokenization(fireTokenChangeEvent = true) {
324
+ this._tokens.flush();
325
+ this._debugBackgroundTokens?.flush();
326
+ if (this._debugBackgroundStates) {
327
+ this._debugBackgroundStates = new TrackingTokenizationStateStore(this._textModel.getLineCount());
328
+ }
329
+ if (fireTokenChangeEvent) {
330
+ this._onDidChangeTokens.fire({
331
+ semanticTokensApplied: false,
332
+ ranges: [
333
+ {
334
+ fromLineNumber: 1,
335
+ toLineNumber: this._textModel.getLineCount(),
336
+ },
337
+ ],
338
+ });
339
+ }
340
+ const initializeTokenization = () => {
341
+ if (this._textModel.isTooLargeForTokenization()) {
342
+ return [null, null];
343
+ }
344
+ const tokenizationSupport = TokenizationRegistry.get(this.getLanguageId());
345
+ if (!tokenizationSupport) {
346
+ return [null, null];
347
+ }
348
+ let initialState;
349
+ try {
350
+ initialState = tokenizationSupport.getInitialState();
351
+ }
352
+ catch (e) {
353
+ onUnexpectedError(e);
354
+ return [null, null];
355
+ }
356
+ return [tokenizationSupport, initialState];
357
+ };
358
+ const [tokenizationSupport, initialState] = initializeTokenization();
359
+ if (tokenizationSupport && initialState) {
360
+ this._tokenizer = new TokenizerWithStateStoreAndTextModel(this._textModel.getLineCount(), tokenizationSupport, this._textModel, this._languageIdCodec);
361
+ }
362
+ else {
363
+ this._tokenizer = null;
364
+ }
365
+ this._backgroundTokenizer.clear();
366
+ this._defaultBackgroundTokenizer = null;
367
+ if (this._tokenizer) {
368
+ const b = {
369
+ setTokens: (tokens) => {
370
+ this.setTokens(tokens);
371
+ },
372
+ backgroundTokenizationFinished: () => {
373
+ if (this._backgroundTokenizationState === 2 /* BackgroundTokenizationState.Completed */) {
374
+ // We already did a full tokenization and don't go back to progressing.
375
+ return;
376
+ }
377
+ const newState = 2 /* BackgroundTokenizationState.Completed */;
378
+ this._backgroundTokenizationState = newState;
379
+ this._onDidChangeBackgroundTokenizationState.fire();
380
+ },
381
+ setEndState: (lineNumber, state) => {
382
+ if (!this._tokenizer) {
383
+ return;
384
+ }
385
+ const firstInvalidEndStateLineNumber = this._tokenizer.store.getFirstInvalidEndStateLineNumber();
386
+ // Don't accept states for definitely valid states, the renderer is ahead of the worker!
387
+ if (firstInvalidEndStateLineNumber !== null && lineNumber >= firstInvalidEndStateLineNumber) {
388
+ this._tokenizer?.store.setEndState(lineNumber, state);
389
+ }
390
+ },
391
+ };
392
+ if (tokenizationSupport && tokenizationSupport.createBackgroundTokenizer && !tokenizationSupport.backgroundTokenizerShouldOnlyVerifyTokens) {
393
+ this._backgroundTokenizer.value = tokenizationSupport.createBackgroundTokenizer(this._textModel, b);
394
+ }
395
+ if (!this._backgroundTokenizer.value && !this._textModel.isTooLargeForTokenization()) {
396
+ this._backgroundTokenizer.value = this._defaultBackgroundTokenizer =
397
+ new DefaultBackgroundTokenizer(this._tokenizer, b);
398
+ this._defaultBackgroundTokenizer.handleChanges();
399
+ }
400
+ if (tokenizationSupport?.backgroundTokenizerShouldOnlyVerifyTokens && tokenizationSupport.createBackgroundTokenizer) {
401
+ this._debugBackgroundTokens = new ContiguousTokensStore(this._languageIdCodec);
402
+ this._debugBackgroundStates = new TrackingTokenizationStateStore(this._textModel.getLineCount());
403
+ this._debugBackgroundTokenizer.clear();
404
+ this._debugBackgroundTokenizer.value = tokenizationSupport.createBackgroundTokenizer(this._textModel, {
405
+ setTokens: (tokens) => {
406
+ this._debugBackgroundTokens?.setMultilineTokens(tokens, this._textModel);
407
+ },
408
+ backgroundTokenizationFinished() {
409
+ // NO OP
410
+ },
411
+ setEndState: (lineNumber, state) => {
412
+ this._debugBackgroundStates?.setEndState(lineNumber, state);
413
+ },
414
+ });
415
+ }
416
+ else {
417
+ this._debugBackgroundTokens = undefined;
418
+ this._debugBackgroundStates = undefined;
419
+ this._debugBackgroundTokenizer.value = undefined;
420
+ }
421
+ }
422
+ this.refreshAllVisibleLineTokens();
423
+ }
424
+ handleDidChangeAttached() {
425
+ this._defaultBackgroundTokenizer?.handleChanges();
426
+ }
427
+ handleDidChangeContent(e) {
428
+ if (e.isFlush) {
429
+ // Don't fire the event, as the view might not have got the text change event yet
430
+ this.resetTokenization(false);
431
+ }
432
+ else if (!e.isEolChange) { // We don't have to do anything on an EOL change
433
+ for (const c of e.changes) {
434
+ const [eolCount, firstLineLength] = countEOL(c.text);
435
+ this._tokens.acceptEdit(c.range, eolCount, firstLineLength);
436
+ this._debugBackgroundTokens?.acceptEdit(c.range, eolCount, firstLineLength);
437
+ }
438
+ this._debugBackgroundStates?.acceptChanges(e.changes);
439
+ if (this._tokenizer) {
440
+ this._tokenizer.store.acceptChanges(e.changes);
441
+ }
442
+ this._defaultBackgroundTokenizer?.handleChanges();
443
+ }
444
+ }
445
+ setTokens(tokens) {
446
+ const { changes } = this._tokens.setMultilineTokens(tokens, this._textModel);
447
+ if (changes.length > 0) {
448
+ this._onDidChangeTokens.fire({ semanticTokensApplied: false, ranges: changes, });
449
+ }
450
+ return { changes: changes };
451
+ }
452
+ refreshAllVisibleLineTokens() {
453
+ const ranges = LineRange.joinMany([...this._attachedViewStates].map(([_, s]) => s.lineRanges));
454
+ this.refreshRanges(ranges);
455
+ }
456
+ refreshRanges(ranges) {
457
+ for (const range of ranges) {
458
+ this.refreshRange(range.startLineNumber, range.endLineNumberExclusive - 1);
459
+ }
460
+ }
461
+ refreshRange(startLineNumber, endLineNumber) {
462
+ if (!this._tokenizer) {
463
+ return;
464
+ }
465
+ startLineNumber = Math.max(1, Math.min(this._textModel.getLineCount(), startLineNumber));
466
+ endLineNumber = Math.min(this._textModel.getLineCount(), endLineNumber);
467
+ const builder = new ContiguousMultilineTokensBuilder();
468
+ const { heuristicTokens } = this._tokenizer.tokenizeHeuristically(builder, startLineNumber, endLineNumber);
469
+ const changedTokens = this.setTokens(builder.finalize());
470
+ if (heuristicTokens) {
471
+ // We overrode tokens with heuristically computed ones.
472
+ // Because old states might get reused (thus stopping invalidation),
473
+ // we have to explicitly request the tokens for the changed ranges again.
474
+ for (const c of changedTokens.changes) {
475
+ this._backgroundTokenizer.value?.requestTokens(c.fromLineNumber, c.toLineNumber + 1);
476
+ }
477
+ }
478
+ this._defaultBackgroundTokenizer?.checkFinished();
479
+ }
480
+ forceTokenization(lineNumber) {
481
+ const builder = new ContiguousMultilineTokensBuilder();
482
+ this._tokenizer?.updateTokensUntilLine(builder, lineNumber);
483
+ this.setTokens(builder.finalize());
484
+ this._defaultBackgroundTokenizer?.checkFinished();
485
+ }
486
+ hasAccurateTokensForLine(lineNumber) {
487
+ if (!this._tokenizer) {
488
+ return true;
489
+ }
490
+ return this._tokenizer.hasAccurateTokensForLine(lineNumber);
491
+ }
492
+ isCheapToTokenize(lineNumber) {
493
+ if (!this._tokenizer) {
494
+ return true;
495
+ }
496
+ return this._tokenizer.isCheapToTokenize(lineNumber);
497
+ }
498
+ getLineTokens(lineNumber) {
499
+ const lineText = this._textModel.getLineContent(lineNumber);
500
+ const result = this._tokens.getTokens(this._textModel.getLanguageId(), lineNumber - 1, lineText);
501
+ if (this._debugBackgroundTokens && this._debugBackgroundStates && this._tokenizer) {
502
+ if (this._debugBackgroundStates.getFirstInvalidEndStateLineNumberOrMax() > lineNumber && this._tokenizer.store.getFirstInvalidEndStateLineNumberOrMax() > lineNumber) {
503
+ const backgroundResult = this._debugBackgroundTokens.getTokens(this._textModel.getLanguageId(), lineNumber - 1, lineText);
504
+ if (!result.equals(backgroundResult) && this._debugBackgroundTokenizer.value?.reportMismatchingTokens) {
505
+ this._debugBackgroundTokenizer.value.reportMismatchingTokens(lineNumber);
506
+ }
507
+ }
508
+ }
509
+ return result;
510
+ }
511
+ getTokenTypeIfInsertingCharacter(lineNumber, column, character) {
512
+ if (!this._tokenizer) {
513
+ return 0 /* StandardTokenType.Other */;
514
+ }
515
+ const position = this._textModel.validatePosition(new Position(lineNumber, column));
516
+ this.forceTokenization(position.lineNumber);
517
+ return this._tokenizer.getTokenTypeIfInsertingCharacter(position, character);
518
+ }
519
+ tokenizeLineWithEdit(position, length, newText) {
520
+ if (!this._tokenizer) {
521
+ return null;
522
+ }
523
+ const validatedPosition = this._textModel.validatePosition(position);
524
+ this.forceTokenization(validatedPosition.lineNumber);
525
+ return this._tokenizer.tokenizeLineWithEdit(validatedPosition, length, newText);
526
+ }
527
+ get hasTokens() {
528
+ return this._tokens.hasTokens;
529
+ }
530
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/tokens.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { equals } from '../../../base/common/arrays.js';
6
+ import { RunOnceScheduler } from '../../../base/common/async.js';
7
+ import { Emitter } from '../../../base/common/event.js';
8
+ import { Disposable } from '../../../base/common/lifecycle.js';
9
+ import { LineRange } from '../core/lineRange.js';
10
+ /**
11
+ * @internal
12
+ */
13
+ export class AttachedViews {
14
+ constructor() {
15
+ this._onDidChangeVisibleRanges = new Emitter();
16
+ this.onDidChangeVisibleRanges = this._onDidChangeVisibleRanges.event;
17
+ this._views = new Set();
18
+ }
19
+ attachView() {
20
+ const view = new AttachedViewImpl((state) => {
21
+ this._onDidChangeVisibleRanges.fire({ view, state });
22
+ });
23
+ this._views.add(view);
24
+ return view;
25
+ }
26
+ detachView(view) {
27
+ this._views.delete(view);
28
+ this._onDidChangeVisibleRanges.fire({ view, state: undefined });
29
+ }
30
+ }
31
+ class AttachedViewImpl {
32
+ constructor(handleStateChange) {
33
+ this.handleStateChange = handleStateChange;
34
+ }
35
+ setVisibleLines(visibleLines, stabilized) {
36
+ const visibleLineRanges = visibleLines.map((line) => new LineRange(line.startLineNumber, line.endLineNumber + 1));
37
+ this.handleStateChange({ visibleLineRanges, stabilized });
38
+ }
39
+ }
40
+ export class AttachedViewHandler extends Disposable {
41
+ get lineRanges() { return this._lineRanges; }
42
+ constructor(_refreshTokens) {
43
+ super();
44
+ this._refreshTokens = _refreshTokens;
45
+ this.runner = this._register(new RunOnceScheduler(() => this.update(), 50));
46
+ this._computedLineRanges = [];
47
+ this._lineRanges = [];
48
+ }
49
+ update() {
50
+ if (equals(this._computedLineRanges, this._lineRanges, (a, b) => a.equals(b))) {
51
+ return;
52
+ }
53
+ this._computedLineRanges = this._lineRanges;
54
+ this._refreshTokens();
55
+ }
56
+ handleStateChange(state) {
57
+ this._lineRanges = state.visibleLineRanges;
58
+ if (state.stabilized) {
59
+ this.runner.cancel();
60
+ this.update();
61
+ }
62
+ else {
63
+ this.runner.schedule();
64
+ }
65
+ }
66
+ }
67
+ export class AbstractTokens extends Disposable {
68
+ get backgroundTokenizationState() {
69
+ return this._backgroundTokenizationState;
70
+ }
71
+ constructor(_languageIdCodec, _textModel, getLanguageId) {
72
+ super();
73
+ this._languageIdCodec = _languageIdCodec;
74
+ this._textModel = _textModel;
75
+ this.getLanguageId = getLanguageId;
76
+ this._backgroundTokenizationState = 1 /* BackgroundTokenizationState.InProgress */;
77
+ this._onDidChangeBackgroundTokenizationState = this._register(new Emitter());
78
+ /** @internal, should not be exposed by the text model! */
79
+ this.onDidChangeBackgroundTokenizationState = this._onDidChangeBackgroundTokenizationState.event;
80
+ this._onDidChangeTokens = this._register(new Emitter());
81
+ /** @internal, should not be exposed by the text model! */
82
+ this.onDidChangeTokens = this._onDidChangeTokens.event;
83
+ }
84
+ tokenizeIfCheap(lineNumber) {
85
+ if (this.isCheapToTokenize(lineNumber)) {
86
+ this.forceTokenization(lineNumber);
87
+ }
88
+ }
89
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/treeSitterTokens.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { TreeSitterTokenizationRegistry } from '../languages.js';
6
+ import { LineTokens } from '../tokens/lineTokens.js';
7
+ import { AbstractTokens } from './tokens.js';
8
+ export class TreeSitterTokens extends AbstractTokens {
9
+ constructor(_treeSitterService, languageIdCodec, textModel, languageId) {
10
+ super(languageIdCodec, textModel, languageId);
11
+ this._treeSitterService = _treeSitterService;
12
+ this._tokenizationSupport = null;
13
+ this._initialize();
14
+ }
15
+ _initialize() {
16
+ const newLanguage = this.getLanguageId();
17
+ if (!this._tokenizationSupport || this._lastLanguageId !== newLanguage) {
18
+ this._lastLanguageId = newLanguage;
19
+ this._tokenizationSupport = TreeSitterTokenizationRegistry.get(newLanguage);
20
+ }
21
+ }
22
+ getLineTokens(lineNumber) {
23
+ const content = this._textModel.getLineContent(lineNumber);
24
+ if (this._tokenizationSupport) {
25
+ const rawTokens = this._tokenizationSupport.tokenizeEncoded(lineNumber, this._textModel);
26
+ if (rawTokens) {
27
+ return new LineTokens(rawTokens, content, this._languageIdCodec);
28
+ }
29
+ }
30
+ return LineTokens.createEmpty(content, this._languageIdCodec);
31
+ }
32
+ resetTokenization(fireTokenChangeEvent = true) {
33
+ if (fireTokenChangeEvent) {
34
+ this._onDidChangeTokens.fire({
35
+ semanticTokensApplied: false,
36
+ ranges: [
37
+ {
38
+ fromLineNumber: 1,
39
+ toLineNumber: this._textModel.getLineCount(),
40
+ },
41
+ ],
42
+ });
43
+ }
44
+ this._initialize();
45
+ }
46
+ handleDidChangeAttached() {
47
+ // TODO @alexr00 implement for background tokenization
48
+ }
49
+ handleDidChangeContent(e) {
50
+ if (e.isFlush) {
51
+ // Don't fire the event, as the view might not have got the text change event yet
52
+ this.resetTokenization(false);
53
+ }
54
+ }
55
+ forceTokenization(lineNumber) {
56
+ // TODO @alexr00 implement
57
+ }
58
+ hasAccurateTokensForLine(lineNumber) {
59
+ // TODO @alexr00 update for background tokenization
60
+ return true;
61
+ }
62
+ isCheapToTokenize(lineNumber) {
63
+ // TODO @alexr00 update for background tokenization
64
+ return true;
65
+ }
66
+ getTokenTypeIfInsertingCharacter(lineNumber, column, character) {
67
+ // TODO @alexr00 implement once we have custom parsing and don't just feed in the whole text model value
68
+ return 0 /* StandardTokenType.Other */;
69
+ }
70
+ tokenizeLineWithEdit(position, length, newText) {
71
+ // TODO @alexr00 understand what this is for and implement
72
+ return null;
73
+ }
74
+ get hasTokens() {
75
+ // TODO @alexr00 once we have a token store, implement properly
76
+ const hasTree = this._treeSitterService.getParseResult(this._textModel) !== undefined;
77
+ return hasTree;
78
+ }
79
+ }
node_modules/monaco-editor/esm/vs/editor/common/model/utils.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * Returns:
7
+ * - -1 => the line consists of whitespace
8
+ * - otherwise => the indent level is returned value
9
+ */
10
+ export function computeIndentLevel(line, tabSize) {
11
+ let indent = 0;
12
+ let i = 0;
13
+ const len = line.length;
14
+ while (i < len) {
15
+ const chCode = line.charCodeAt(i);
16
+ if (chCode === 32 /* CharCode.Space */) {
17
+ indent++;
18
+ }
19
+ else if (chCode === 9 /* CharCode.Tab */) {
20
+ indent = indent - indent % tabSize + tabSize;
21
+ }
22
+ else {
23
+ break;
24
+ }
25
+ i++;
26
+ }
27
+ if (i === len) {
28
+ return -1; // line only consists of whitespace
29
+ }
30
+ return indent;
31
+ }
node_modules/monaco-editor/esm/vs/editor/common/modelLineProjectionData.js ADDED
@@ -0,0 +1,299 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { assertNever } from '../../base/common/assert.js';
6
+ import { Position } from './core/position.js';
7
+ import { InjectedTextCursorStops } from './model.js';
8
+ /**
9
+ * *input*:
10
+ * ```
11
+ * xxxxxxxxxxxxxxxxxxxxxxxxxxx
12
+ * ```
13
+ *
14
+ * -> Applying injections `[i...i]`, *inputWithInjections*:
15
+ * ```
16
+ * xxxxxx[iiiiiiiiii]xxxxxxxxxxxxxxxxx[ii]xxxx
17
+ * ```
18
+ *
19
+ * -> breaking at offsets `|` in `xxxxxx[iiiiiii|iii]xxxxxxxxxxx|xxxxxx[ii]xxxx|`:
20
+ * ```
21
+ * xxxxxx[iiiiiii
22
+ * iii]xxxxxxxxxxx
23
+ * xxxxxx[ii]xxxx
24
+ * ```
25
+ *
26
+ * -> applying wrappedTextIndentLength, *output*:
27
+ * ```
28
+ * xxxxxx[iiiiiii
29
+ * iii]xxxxxxxxxxx
30
+ * xxxxxx[ii]xxxx
31
+ * ```
32
+ */
33
+ export class ModelLineProjectionData {
34
+ constructor(injectionOffsets,
35
+ /**
36
+ * `injectionOptions.length` must equal `injectionOffsets.length`
37
+ */
38
+ injectionOptions,
39
+ /**
40
+ * Refers to offsets after applying injections to the source.
41
+ * The last break offset indicates the length of the source after applying injections.
42
+ */
43
+ breakOffsets,
44
+ /**
45
+ * Refers to offsets after applying injections
46
+ */
47
+ breakOffsetsVisibleColumn, wrappedTextIndentLength) {
48
+ this.injectionOffsets = injectionOffsets;
49
+ this.injectionOptions = injectionOptions;
50
+ this.breakOffsets = breakOffsets;
51
+ this.breakOffsetsVisibleColumn = breakOffsetsVisibleColumn;
52
+ this.wrappedTextIndentLength = wrappedTextIndentLength;
53
+ }
54
+ getOutputLineCount() {
55
+ return this.breakOffsets.length;
56
+ }
57
+ getMinOutputOffset(outputLineIndex) {
58
+ if (outputLineIndex > 0) {
59
+ return this.wrappedTextIndentLength;
60
+ }
61
+ return 0;
62
+ }
63
+ getLineLength(outputLineIndex) {
64
+ // These offsets refer to model text with injected text.
65
+ const startOffset = outputLineIndex > 0 ? this.breakOffsets[outputLineIndex - 1] : 0;
66
+ const endOffset = this.breakOffsets[outputLineIndex];
67
+ let lineLength = endOffset - startOffset;
68
+ if (outputLineIndex > 0) {
69
+ lineLength += this.wrappedTextIndentLength;
70
+ }
71
+ return lineLength;
72
+ }
73
+ getMaxOutputOffset(outputLineIndex) {
74
+ return this.getLineLength(outputLineIndex);
75
+ }
76
+ translateToInputOffset(outputLineIndex, outputOffset) {
77
+ if (outputLineIndex > 0) {
78
+ outputOffset = Math.max(0, outputOffset - this.wrappedTextIndentLength);
79
+ }
80
+ const offsetInInputWithInjection = outputLineIndex === 0 ? outputOffset : this.breakOffsets[outputLineIndex - 1] + outputOffset;
81
+ let offsetInInput = offsetInInputWithInjection;
82
+ if (this.injectionOffsets !== null) {
83
+ for (let i = 0; i < this.injectionOffsets.length; i++) {
84
+ if (offsetInInput > this.injectionOffsets[i]) {
85
+ if (offsetInInput < this.injectionOffsets[i] + this.injectionOptions[i].content.length) {
86
+ // `inputOffset` is within injected text
87
+ offsetInInput = this.injectionOffsets[i];
88
+ }
89
+ else {
90
+ offsetInInput -= this.injectionOptions[i].content.length;
91
+ }
92
+ }
93
+ else {
94
+ break;
95
+ }
96
+ }
97
+ }
98
+ return offsetInInput;
99
+ }
100
+ translateToOutputPosition(inputOffset, affinity = 2 /* PositionAffinity.None */) {
101
+ let inputOffsetInInputWithInjection = inputOffset;
102
+ if (this.injectionOffsets !== null) {
103
+ for (let i = 0; i < this.injectionOffsets.length; i++) {
104
+ if (inputOffset < this.injectionOffsets[i]) {
105
+ break;
106
+ }
107
+ if (affinity !== 1 /* PositionAffinity.Right */ && inputOffset === this.injectionOffsets[i]) {
108
+ break;
109
+ }
110
+ inputOffsetInInputWithInjection += this.injectionOptions[i].content.length;
111
+ }
112
+ }
113
+ return this.offsetInInputWithInjectionsToOutputPosition(inputOffsetInInputWithInjection, affinity);
114
+ }
115
+ offsetInInputWithInjectionsToOutputPosition(offsetInInputWithInjections, affinity = 2 /* PositionAffinity.None */) {
116
+ let low = 0;
117
+ let high = this.breakOffsets.length - 1;
118
+ let mid = 0;
119
+ let midStart = 0;
120
+ while (low <= high) {
121
+ mid = low + ((high - low) / 2) | 0;
122
+ const midStop = this.breakOffsets[mid];
123
+ midStart = mid > 0 ? this.breakOffsets[mid - 1] : 0;
124
+ if (affinity === 0 /* PositionAffinity.Left */) {
125
+ if (offsetInInputWithInjections <= midStart) {
126
+ high = mid - 1;
127
+ }
128
+ else if (offsetInInputWithInjections > midStop) {
129
+ low = mid + 1;
130
+ }
131
+ else {
132
+ break;
133
+ }
134
+ }
135
+ else {
136
+ if (offsetInInputWithInjections < midStart) {
137
+ high = mid - 1;
138
+ }
139
+ else if (offsetInInputWithInjections >= midStop) {
140
+ low = mid + 1;
141
+ }
142
+ else {
143
+ break;
144
+ }
145
+ }
146
+ }
147
+ let outputOffset = offsetInInputWithInjections - midStart;
148
+ if (mid > 0) {
149
+ outputOffset += this.wrappedTextIndentLength;
150
+ }
151
+ return new OutputPosition(mid, outputOffset);
152
+ }
153
+ normalizeOutputPosition(outputLineIndex, outputOffset, affinity) {
154
+ if (this.injectionOffsets !== null) {
155
+ const offsetInInputWithInjections = this.outputPositionToOffsetInInputWithInjections(outputLineIndex, outputOffset);
156
+ const normalizedOffsetInUnwrappedLine = this.normalizeOffsetInInputWithInjectionsAroundInjections(offsetInInputWithInjections, affinity);
157
+ if (normalizedOffsetInUnwrappedLine !== offsetInInputWithInjections) {
158
+ // injected text caused a change
159
+ return this.offsetInInputWithInjectionsToOutputPosition(normalizedOffsetInUnwrappedLine, affinity);
160
+ }
161
+ }
162
+ if (affinity === 0 /* PositionAffinity.Left */) {
163
+ if (outputLineIndex > 0 && outputOffset === this.getMinOutputOffset(outputLineIndex)) {
164
+ return new OutputPosition(outputLineIndex - 1, this.getMaxOutputOffset(outputLineIndex - 1));
165
+ }
166
+ }
167
+ else if (affinity === 1 /* PositionAffinity.Right */) {
168
+ const maxOutputLineIndex = this.getOutputLineCount() - 1;
169
+ if (outputLineIndex < maxOutputLineIndex && outputOffset === this.getMaxOutputOffset(outputLineIndex)) {
170
+ return new OutputPosition(outputLineIndex + 1, this.getMinOutputOffset(outputLineIndex + 1));
171
+ }
172
+ }
173
+ return new OutputPosition(outputLineIndex, outputOffset);
174
+ }
175
+ outputPositionToOffsetInInputWithInjections(outputLineIndex, outputOffset) {
176
+ if (outputLineIndex > 0) {
177
+ outputOffset = Math.max(0, outputOffset - this.wrappedTextIndentLength);
178
+ }
179
+ const result = (outputLineIndex > 0 ? this.breakOffsets[outputLineIndex - 1] : 0) + outputOffset;
180
+ return result;
181
+ }
182
+ normalizeOffsetInInputWithInjectionsAroundInjections(offsetInInputWithInjections, affinity) {
183
+ const injectedText = this.getInjectedTextAtOffset(offsetInInputWithInjections);
184
+ if (!injectedText) {
185
+ return offsetInInputWithInjections;
186
+ }
187
+ if (affinity === 2 /* PositionAffinity.None */) {
188
+ if (offsetInInputWithInjections === injectedText.offsetInInputWithInjections + injectedText.length
189
+ && hasRightCursorStop(this.injectionOptions[injectedText.injectedTextIndex].cursorStops)) {
190
+ return injectedText.offsetInInputWithInjections + injectedText.length;
191
+ }
192
+ else {
193
+ let result = injectedText.offsetInInputWithInjections;
194
+ if (hasLeftCursorStop(this.injectionOptions[injectedText.injectedTextIndex].cursorStops)) {
195
+ return result;
196
+ }
197
+ let index = injectedText.injectedTextIndex - 1;
198
+ while (index >= 0 && this.injectionOffsets[index] === this.injectionOffsets[injectedText.injectedTextIndex]) {
199
+ if (hasRightCursorStop(this.injectionOptions[index].cursorStops)) {
200
+ break;
201
+ }
202
+ result -= this.injectionOptions[index].content.length;
203
+ if (hasLeftCursorStop(this.injectionOptions[index].cursorStops)) {
204
+ break;
205
+ }
206
+ index--;
207
+ }
208
+ return result;
209
+ }
210
+ }
211
+ else if (affinity === 1 /* PositionAffinity.Right */ || affinity === 4 /* PositionAffinity.RightOfInjectedText */) {
212
+ let result = injectedText.offsetInInputWithInjections + injectedText.length;
213
+ let index = injectedText.injectedTextIndex;
214
+ // traverse all injected text that touch each other
215
+ while (index + 1 < this.injectionOffsets.length && this.injectionOffsets[index + 1] === this.injectionOffsets[index]) {
216
+ result += this.injectionOptions[index + 1].content.length;
217
+ index++;
218
+ }
219
+ return result;
220
+ }
221
+ else if (affinity === 0 /* PositionAffinity.Left */ || affinity === 3 /* PositionAffinity.LeftOfInjectedText */) {
222
+ // affinity is left
223
+ let result = injectedText.offsetInInputWithInjections;
224
+ let index = injectedText.injectedTextIndex;
225
+ // traverse all injected text that touch each other
226
+ while (index - 1 >= 0 && this.injectionOffsets[index - 1] === this.injectionOffsets[index]) {
227
+ result -= this.injectionOptions[index - 1].content.length;
228
+ index--;
229
+ }
230
+ return result;
231
+ }
232
+ assertNever(affinity);
233
+ }
234
+ getInjectedText(outputLineIndex, outputOffset) {
235
+ const offset = this.outputPositionToOffsetInInputWithInjections(outputLineIndex, outputOffset);
236
+ const injectedText = this.getInjectedTextAtOffset(offset);
237
+ if (!injectedText) {
238
+ return null;
239
+ }
240
+ return {
241
+ options: this.injectionOptions[injectedText.injectedTextIndex]
242
+ };
243
+ }
244
+ getInjectedTextAtOffset(offsetInInputWithInjections) {
245
+ const injectionOffsets = this.injectionOffsets;
246
+ const injectionOptions = this.injectionOptions;
247
+ if (injectionOffsets !== null) {
248
+ let totalInjectedTextLengthBefore = 0;
249
+ for (let i = 0; i < injectionOffsets.length; i++) {
250
+ const length = injectionOptions[i].content.length;
251
+ const injectedTextStartOffsetInInputWithInjections = injectionOffsets[i] + totalInjectedTextLengthBefore;
252
+ const injectedTextEndOffsetInInputWithInjections = injectionOffsets[i] + totalInjectedTextLengthBefore + length;
253
+ if (injectedTextStartOffsetInInputWithInjections > offsetInInputWithInjections) {
254
+ // Injected text starts later.
255
+ break; // All later injected texts have an even larger offset.
256
+ }
257
+ if (offsetInInputWithInjections <= injectedTextEndOffsetInInputWithInjections) {
258
+ // Injected text ends after or with the given position (but also starts with or before it).
259
+ return {
260
+ injectedTextIndex: i,
261
+ offsetInInputWithInjections: injectedTextStartOffsetInInputWithInjections,
262
+ length
263
+ };
264
+ }
265
+ totalInjectedTextLengthBefore += length;
266
+ }
267
+ }
268
+ return undefined;
269
+ }
270
+ }
271
+ function hasRightCursorStop(cursorStop) {
272
+ if (cursorStop === null || cursorStop === undefined) {
273
+ return true;
274
+ }
275
+ return cursorStop === InjectedTextCursorStops.Right || cursorStop === InjectedTextCursorStops.Both;
276
+ }
277
+ function hasLeftCursorStop(cursorStop) {
278
+ if (cursorStop === null || cursorStop === undefined) {
279
+ return true;
280
+ }
281
+ return cursorStop === InjectedTextCursorStops.Left || cursorStop === InjectedTextCursorStops.Both;
282
+ }
283
+ export class InjectedText {
284
+ constructor(options) {
285
+ this.options = options;
286
+ }
287
+ }
288
+ export class OutputPosition {
289
+ constructor(outputLineIndex, outputOffset) {
290
+ this.outputLineIndex = outputLineIndex;
291
+ this.outputOffset = outputOffset;
292
+ }
293
+ toString() {
294
+ return `${this.outputLineIndex}:${this.outputOffset}`;
295
+ }
296
+ toPosition(baseLineNumber) {
297
+ return new Position(baseLineNumber + this.outputLineIndex, this.outputOffset + 1);
298
+ }
299
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/editorBaseApi.js ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { CancellationTokenSource } from '../../../base/common/cancellation.js';
6
+ import { Emitter } from '../../../base/common/event.js';
7
+ import { KeyChord } from '../../../base/common/keyCodes.js';
8
+ import { URI } from '../../../base/common/uri.js';
9
+ import { Position } from '../core/position.js';
10
+ import { Range } from '../core/range.js';
11
+ import { Selection } from '../core/selection.js';
12
+ import { Token } from '../languages.js';
13
+ import * as standaloneEnums from '../standalone/standaloneEnums.js';
14
+ export class KeyMod {
15
+ static { this.CtrlCmd = 2048 /* ConstKeyMod.CtrlCmd */; }
16
+ static { this.Shift = 1024 /* ConstKeyMod.Shift */; }
17
+ static { this.Alt = 512 /* ConstKeyMod.Alt */; }
18
+ static { this.WinCtrl = 256 /* ConstKeyMod.WinCtrl */; }
19
+ static chord(firstPart, secondPart) {
20
+ return KeyChord(firstPart, secondPart);
21
+ }
22
+ }
23
+ export function createMonacoBaseAPI() {
24
+ return {
25
+ editor: undefined, // undefined override expected here
26
+ languages: undefined, // undefined override expected here
27
+ CancellationTokenSource: CancellationTokenSource,
28
+ Emitter: Emitter,
29
+ KeyCode: standaloneEnums.KeyCode,
30
+ KeyMod: KeyMod,
31
+ Position: Position,
32
+ Range: Range,
33
+ Selection: Selection,
34
+ SelectionDirection: standaloneEnums.SelectionDirection,
35
+ MarkerSeverity: standaloneEnums.MarkerSeverity,
36
+ MarkerTag: standaloneEnums.MarkerTag,
37
+ Uri: URI,
38
+ Token: Token
39
+ };
40
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/editorSimpleWorker.js ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { stringDiff } from '../../../base/common/diff/diff.js';
6
+ import { Range } from '../core/range.js';
7
+ import { computeLinks } from '../languages/linkComputer.js';
8
+ import { BasicInplaceReplace } from '../languages/supports/inplaceReplaceSupport.js';
9
+ import { createMonacoBaseAPI } from './editorBaseApi.js';
10
+ import { EditorWorkerHost } from './editorWorkerHost.js';
11
+ import { StopWatch } from '../../../base/common/stopwatch.js';
12
+ import { UnicodeTextModelHighlighter } from './unicodeTextModelHighlighter.js';
13
+ import { linesDiffComputers } from '../diff/linesDiffComputers.js';
14
+ import { createProxyObject, getAllMethodNames } from '../../../base/common/objects.js';
15
+ import { FileAccess } from '../../../base/common/network.js';
16
+ import { computeDefaultDocumentColors } from '../languages/defaultDocumentColorsComputer.js';
17
+ import { findSectionHeaders } from './findSectionHeaders.js';
18
+ import { WorkerTextModelSyncServer } from './textModelSync/textModelSync.impl.js';
19
+ // ESM-comment-begin
20
+ // const isESM = false;
21
+ // ESM-comment-end
22
+ // ESM-uncomment-begin
23
+ const isESM = true;
24
+ /**
25
+ * @internal
26
+ */
27
+ export class BaseEditorSimpleWorker {
28
+ constructor() {
29
+ this._workerTextModelSyncServer = new WorkerTextModelSyncServer();
30
+ }
31
+ dispose() {
32
+ }
33
+ _getModel(uri) {
34
+ return this._workerTextModelSyncServer.getModel(uri);
35
+ }
36
+ _getModels() {
37
+ return this._workerTextModelSyncServer.getModels();
38
+ }
39
+ $acceptNewModel(data) {
40
+ this._workerTextModelSyncServer.$acceptNewModel(data);
41
+ }
42
+ $acceptModelChanged(uri, e) {
43
+ this._workerTextModelSyncServer.$acceptModelChanged(uri, e);
44
+ }
45
+ $acceptRemovedModel(uri) {
46
+ this._workerTextModelSyncServer.$acceptRemovedModel(uri);
47
+ }
48
+ async $computeUnicodeHighlights(url, options, range) {
49
+ const model = this._getModel(url);
50
+ if (!model) {
51
+ return { ranges: [], hasMore: false, ambiguousCharacterCount: 0, invisibleCharacterCount: 0, nonBasicAsciiCharacterCount: 0 };
52
+ }
53
+ return UnicodeTextModelHighlighter.computeUnicodeHighlights(model, options, range);
54
+ }
55
+ async $findSectionHeaders(url, options) {
56
+ const model = this._getModel(url);
57
+ if (!model) {
58
+ return [];
59
+ }
60
+ return findSectionHeaders(model, options);
61
+ }
62
+ // ---- BEGIN diff --------------------------------------------------------------------------
63
+ async $computeDiff(originalUrl, modifiedUrl, options, algorithm) {
64
+ const original = this._getModel(originalUrl);
65
+ const modified = this._getModel(modifiedUrl);
66
+ if (!original || !modified) {
67
+ return null;
68
+ }
69
+ const result = EditorSimpleWorker.computeDiff(original, modified, options, algorithm);
70
+ return result;
71
+ }
72
+ static computeDiff(originalTextModel, modifiedTextModel, options, algorithm) {
73
+ const diffAlgorithm = algorithm === 'advanced' ? linesDiffComputers.getDefault() : linesDiffComputers.getLegacy();
74
+ const originalLines = originalTextModel.getLinesContent();
75
+ const modifiedLines = modifiedTextModel.getLinesContent();
76
+ const result = diffAlgorithm.computeDiff(originalLines, modifiedLines, options);
77
+ const identical = (result.changes.length > 0 ? false : this._modelsAreIdentical(originalTextModel, modifiedTextModel));
78
+ function getLineChanges(changes) {
79
+ return changes.map(m => ([m.original.startLineNumber, m.original.endLineNumberExclusive, m.modified.startLineNumber, m.modified.endLineNumberExclusive, m.innerChanges?.map(m => [
80
+ m.originalRange.startLineNumber,
81
+ m.originalRange.startColumn,
82
+ m.originalRange.endLineNumber,
83
+ m.originalRange.endColumn,
84
+ m.modifiedRange.startLineNumber,
85
+ m.modifiedRange.startColumn,
86
+ m.modifiedRange.endLineNumber,
87
+ m.modifiedRange.endColumn,
88
+ ])]));
89
+ }
90
+ return {
91
+ identical,
92
+ quitEarly: result.hitTimeout,
93
+ changes: getLineChanges(result.changes),
94
+ moves: result.moves.map(m => ([
95
+ m.lineRangeMapping.original.startLineNumber,
96
+ m.lineRangeMapping.original.endLineNumberExclusive,
97
+ m.lineRangeMapping.modified.startLineNumber,
98
+ m.lineRangeMapping.modified.endLineNumberExclusive,
99
+ getLineChanges(m.changes)
100
+ ])),
101
+ };
102
+ }
103
+ static _modelsAreIdentical(original, modified) {
104
+ const originalLineCount = original.getLineCount();
105
+ const modifiedLineCount = modified.getLineCount();
106
+ if (originalLineCount !== modifiedLineCount) {
107
+ return false;
108
+ }
109
+ for (let line = 1; line <= originalLineCount; line++) {
110
+ const originalLine = original.getLineContent(line);
111
+ const modifiedLine = modified.getLineContent(line);
112
+ if (originalLine !== modifiedLine) {
113
+ return false;
114
+ }
115
+ }
116
+ return true;
117
+ }
118
+ // ---- END diff --------------------------------------------------------------------------
119
+ // ---- BEGIN minimal edits ---------------------------------------------------------------
120
+ static { this._diffLimit = 100000; }
121
+ async $computeMoreMinimalEdits(modelUrl, edits, pretty) {
122
+ const model = this._getModel(modelUrl);
123
+ if (!model) {
124
+ return edits;
125
+ }
126
+ const result = [];
127
+ let lastEol = undefined;
128
+ edits = edits.slice(0).sort((a, b) => {
129
+ if (a.range && b.range) {
130
+ return Range.compareRangesUsingStarts(a.range, b.range);
131
+ }
132
+ // eol only changes should go to the end
133
+ const aRng = a.range ? 0 : 1;
134
+ const bRng = b.range ? 0 : 1;
135
+ return aRng - bRng;
136
+ });
137
+ // merge adjacent edits
138
+ let writeIndex = 0;
139
+ for (let readIndex = 1; readIndex < edits.length; readIndex++) {
140
+ if (Range.getEndPosition(edits[writeIndex].range).equals(Range.getStartPosition(edits[readIndex].range))) {
141
+ edits[writeIndex].range = Range.fromPositions(Range.getStartPosition(edits[writeIndex].range), Range.getEndPosition(edits[readIndex].range));
142
+ edits[writeIndex].text += edits[readIndex].text;
143
+ }
144
+ else {
145
+ writeIndex++;
146
+ edits[writeIndex] = edits[readIndex];
147
+ }
148
+ }
149
+ edits.length = writeIndex + 1;
150
+ for (let { range, text, eol } of edits) {
151
+ if (typeof eol === 'number') {
152
+ lastEol = eol;
153
+ }
154
+ if (Range.isEmpty(range) && !text) {
155
+ // empty change
156
+ continue;
157
+ }
158
+ const original = model.getValueInRange(range);
159
+ text = text.replace(/\r\n|\n|\r/g, model.eol);
160
+ if (original === text) {
161
+ // noop
162
+ continue;
163
+ }
164
+ // make sure diff won't take too long
165
+ if (Math.max(text.length, original.length) > EditorSimpleWorker._diffLimit) {
166
+ result.push({ range, text });
167
+ continue;
168
+ }
169
+ // compute diff between original and edit.text
170
+ const changes = stringDiff(original, text, pretty);
171
+ const editOffset = model.offsetAt(Range.lift(range).getStartPosition());
172
+ for (const change of changes) {
173
+ const start = model.positionAt(editOffset + change.originalStart);
174
+ const end = model.positionAt(editOffset + change.originalStart + change.originalLength);
175
+ const newEdit = {
176
+ text: text.substr(change.modifiedStart, change.modifiedLength),
177
+ range: { startLineNumber: start.lineNumber, startColumn: start.column, endLineNumber: end.lineNumber, endColumn: end.column }
178
+ };
179
+ if (model.getValueInRange(newEdit.range) !== newEdit.text) {
180
+ result.push(newEdit);
181
+ }
182
+ }
183
+ }
184
+ if (typeof lastEol === 'number') {
185
+ result.push({ eol: lastEol, text: '', range: { startLineNumber: 0, startColumn: 0, endLineNumber: 0, endColumn: 0 } });
186
+ }
187
+ return result;
188
+ }
189
+ // ---- END minimal edits ---------------------------------------------------------------
190
+ async $computeLinks(modelUrl) {
191
+ const model = this._getModel(modelUrl);
192
+ if (!model) {
193
+ return null;
194
+ }
195
+ return computeLinks(model);
196
+ }
197
+ // --- BEGIN default document colors -----------------------------------------------------------
198
+ async $computeDefaultDocumentColors(modelUrl) {
199
+ const model = this._getModel(modelUrl);
200
+ if (!model) {
201
+ return null;
202
+ }
203
+ return computeDefaultDocumentColors(model);
204
+ }
205
+ // ---- BEGIN suggest --------------------------------------------------------------------------
206
+ static { this._suggestionsLimit = 10000; }
207
+ async $textualSuggest(modelUrls, leadingWord, wordDef, wordDefFlags) {
208
+ const sw = new StopWatch();
209
+ const wordDefRegExp = new RegExp(wordDef, wordDefFlags);
210
+ const seen = new Set();
211
+ outer: for (const url of modelUrls) {
212
+ const model = this._getModel(url);
213
+ if (!model) {
214
+ continue;
215
+ }
216
+ for (const word of model.words(wordDefRegExp)) {
217
+ if (word === leadingWord || !isNaN(Number(word))) {
218
+ continue;
219
+ }
220
+ seen.add(word);
221
+ if (seen.size > EditorSimpleWorker._suggestionsLimit) {
222
+ break outer;
223
+ }
224
+ }
225
+ }
226
+ return { words: Array.from(seen), duration: sw.elapsed() };
227
+ }
228
+ // ---- END suggest --------------------------------------------------------------------------
229
+ //#region -- word ranges --
230
+ async $computeWordRanges(modelUrl, range, wordDef, wordDefFlags) {
231
+ const model = this._getModel(modelUrl);
232
+ if (!model) {
233
+ return Object.create(null);
234
+ }
235
+ const wordDefRegExp = new RegExp(wordDef, wordDefFlags);
236
+ const result = Object.create(null);
237
+ for (let line = range.startLineNumber; line < range.endLineNumber; line++) {
238
+ const words = model.getLineWords(line, wordDefRegExp);
239
+ for (const word of words) {
240
+ if (!isNaN(Number(word.word))) {
241
+ continue;
242
+ }
243
+ let array = result[word.word];
244
+ if (!array) {
245
+ array = [];
246
+ result[word.word] = array;
247
+ }
248
+ array.push({
249
+ startLineNumber: line,
250
+ startColumn: word.startColumn,
251
+ endLineNumber: line,
252
+ endColumn: word.endColumn
253
+ });
254
+ }
255
+ }
256
+ return result;
257
+ }
258
+ //#endregion
259
+ async $navigateValueSet(modelUrl, range, up, wordDef, wordDefFlags) {
260
+ const model = this._getModel(modelUrl);
261
+ if (!model) {
262
+ return null;
263
+ }
264
+ const wordDefRegExp = new RegExp(wordDef, wordDefFlags);
265
+ if (range.startColumn === range.endColumn) {
266
+ range = {
267
+ startLineNumber: range.startLineNumber,
268
+ startColumn: range.startColumn,
269
+ endLineNumber: range.endLineNumber,
270
+ endColumn: range.endColumn + 1
271
+ };
272
+ }
273
+ const selectionText = model.getValueInRange(range);
274
+ const wordRange = model.getWordAtPosition({ lineNumber: range.startLineNumber, column: range.startColumn }, wordDefRegExp);
275
+ if (!wordRange) {
276
+ return null;
277
+ }
278
+ const word = model.getValueInRange(wordRange);
279
+ const result = BasicInplaceReplace.INSTANCE.navigateValueSet(range, selectionText, wordRange, word, up);
280
+ return result;
281
+ }
282
+ }
283
+ /**
284
+ * @internal
285
+ */
286
+ export class EditorSimpleWorker extends BaseEditorSimpleWorker {
287
+ constructor(_host, _foreignModuleFactory) {
288
+ super();
289
+ this._host = _host;
290
+ this._foreignModuleFactory = _foreignModuleFactory;
291
+ this._foreignModule = null;
292
+ }
293
+ async $ping() {
294
+ return 'pong';
295
+ }
296
+ // ---- BEGIN foreign module support --------------------------------------------------------------------------
297
+ $loadForeignModule(moduleId, createData, foreignHostMethods) {
298
+ const proxyMethodRequest = (method, args) => {
299
+ return this._host.$fhr(method, args);
300
+ };
301
+ const foreignHost = createProxyObject(foreignHostMethods, proxyMethodRequest);
302
+ const ctx = {
303
+ host: foreignHost,
304
+ getMirrorModels: () => {
305
+ return this._getModels();
306
+ }
307
+ };
308
+ if (this._foreignModuleFactory) {
309
+ this._foreignModule = this._foreignModuleFactory(ctx, createData);
310
+ // static foreing module
311
+ return Promise.resolve(getAllMethodNames(this._foreignModule));
312
+ }
313
+ return new Promise((resolve, reject) => {
314
+ const onModuleCallback = (foreignModule) => {
315
+ this._foreignModule = foreignModule.create(ctx, createData);
316
+ resolve(getAllMethodNames(this._foreignModule));
317
+ };
318
+ if (!isESM) {
319
+ require([`${moduleId}`], onModuleCallback, reject);
320
+ }
321
+ else {
322
+ const url = FileAccess.asBrowserUri(`${moduleId}.js`).toString(true);
323
+ import(`${url}`).then(onModuleCallback).catch(reject);
324
+ }
325
+ });
326
+ }
327
+ // foreign method request
328
+ $fmr(method, args) {
329
+ if (!this._foreignModule || typeof this._foreignModule[method] !== 'function') {
330
+ return Promise.reject(new Error('Missing requestHandler or method: ' + method));
331
+ }
332
+ try {
333
+ return Promise.resolve(this._foreignModule[method].apply(this._foreignModule, args));
334
+ }
335
+ catch (e) {
336
+ return Promise.reject(e);
337
+ }
338
+ }
339
+ }
340
+ /**
341
+ * Defines the worker entry point. Must be exported and named `create`.
342
+ * @skipMangle
343
+ * @internal
344
+ */
345
+ export function create(workerServer) {
346
+ return new EditorSimpleWorker(EditorWorkerHost.getChannel(workerServer), null);
347
+ }
348
+ if (typeof importScripts === 'function') {
349
+ // Running in a web worker
350
+ globalThis.monaco = createMonacoBaseAPI();
351
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/editorWorker.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
6
+ export const IEditorWorkerService = createDecorator('editorWorkerService');
node_modules/monaco-editor/esm/vs/editor/common/services/editorWorkerHost.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export class EditorWorkerHost {
6
+ static { this.CHANNEL_NAME = 'editorWorkerHost'; }
7
+ static getChannel(workerServer) {
8
+ return workerServer.getChannel(EditorWorkerHost.CHANNEL_NAME);
9
+ }
10
+ static setChannel(workerClient, obj) {
11
+ workerClient.setChannel(EditorWorkerHost.CHANNEL_NAME, obj);
12
+ }
13
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/findSectionHeaders.js ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ const markRegex = new RegExp('\\bMARK:\\s*(.*)$', 'd');
6
+ const trimDashesRegex = /^-+|-+$/g;
7
+ /**
8
+ * Find section headers in the model.
9
+ *
10
+ * @param model the text model to search in
11
+ * @param options options to search with
12
+ * @returns an array of section headers
13
+ */
14
+ export function findSectionHeaders(model, options) {
15
+ let headers = [];
16
+ if (options.findRegionSectionHeaders && options.foldingRules?.markers) {
17
+ const regionHeaders = collectRegionHeaders(model, options);
18
+ headers = headers.concat(regionHeaders);
19
+ }
20
+ if (options.findMarkSectionHeaders) {
21
+ const markHeaders = collectMarkHeaders(model);
22
+ headers = headers.concat(markHeaders);
23
+ }
24
+ return headers;
25
+ }
26
+ function collectRegionHeaders(model, options) {
27
+ const regionHeaders = [];
28
+ const endLineNumber = model.getLineCount();
29
+ for (let lineNumber = 1; lineNumber <= endLineNumber; lineNumber++) {
30
+ const lineContent = model.getLineContent(lineNumber);
31
+ const match = lineContent.match(options.foldingRules.markers.start);
32
+ if (match) {
33
+ const range = { startLineNumber: lineNumber, startColumn: match[0].length + 1, endLineNumber: lineNumber, endColumn: lineContent.length + 1 };
34
+ if (range.endColumn > range.startColumn) {
35
+ const sectionHeader = {
36
+ range,
37
+ ...getHeaderText(lineContent.substring(match[0].length)),
38
+ shouldBeInComments: false
39
+ };
40
+ if (sectionHeader.text || sectionHeader.hasSeparatorLine) {
41
+ regionHeaders.push(sectionHeader);
42
+ }
43
+ }
44
+ }
45
+ }
46
+ return regionHeaders;
47
+ }
48
+ function collectMarkHeaders(model) {
49
+ const markHeaders = [];
50
+ const endLineNumber = model.getLineCount();
51
+ for (let lineNumber = 1; lineNumber <= endLineNumber; lineNumber++) {
52
+ const lineContent = model.getLineContent(lineNumber);
53
+ addMarkHeaderIfFound(lineContent, lineNumber, markHeaders);
54
+ }
55
+ return markHeaders;
56
+ }
57
+ function addMarkHeaderIfFound(lineContent, lineNumber, sectionHeaders) {
58
+ markRegex.lastIndex = 0;
59
+ const match = markRegex.exec(lineContent);
60
+ if (match) {
61
+ const column = match.indices[1][0] + 1;
62
+ const endColumn = match.indices[1][1] + 1;
63
+ const range = { startLineNumber: lineNumber, startColumn: column, endLineNumber: lineNumber, endColumn: endColumn };
64
+ if (range.endColumn > range.startColumn) {
65
+ const sectionHeader = {
66
+ range,
67
+ ...getHeaderText(match[1]),
68
+ shouldBeInComments: true
69
+ };
70
+ if (sectionHeader.text || sectionHeader.hasSeparatorLine) {
71
+ sectionHeaders.push(sectionHeader);
72
+ }
73
+ }
74
+ }
75
+ }
76
+ function getHeaderText(text) {
77
+ text = text.trim();
78
+ const hasSeparatorLine = text.startsWith('-');
79
+ text = text.replace(trimDashesRegex, '');
80
+ return { text, hasSeparatorLine };
81
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/getIconClasses.js ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { Schemas } from '../../../base/common/network.js';
6
+ import { DataUri } from '../../../base/common/resources.js';
7
+ import { URI } from '../../../base/common/uri.js';
8
+ import { PLAINTEXT_LANGUAGE_ID } from '../languages/modesRegistry.js';
9
+ import { FileKind } from '../../../platform/files/common/files.js';
10
+ import { ThemeIcon } from '../../../base/common/themables.js';
11
+ const fileIconDirectoryRegex = /(?:\/|^)(?:([^\/]+)\/)?([^\/]+)$/;
12
+ export function getIconClasses(modelService, languageService, resource, fileKind, icon) {
13
+ if (ThemeIcon.isThemeIcon(icon)) {
14
+ return [`codicon-${icon.id}`, 'predefined-file-icon'];
15
+ }
16
+ if (URI.isUri(icon)) {
17
+ return [];
18
+ }
19
+ // we always set these base classes even if we do not have a path
20
+ const classes = fileKind === FileKind.ROOT_FOLDER ? ['rootfolder-icon'] : fileKind === FileKind.FOLDER ? ['folder-icon'] : ['file-icon'];
21
+ if (resource) {
22
+ // Get the path and name of the resource. For data-URIs, we need to parse specially
23
+ let name;
24
+ if (resource.scheme === Schemas.data) {
25
+ const metadata = DataUri.parseMetaData(resource);
26
+ name = metadata.get(DataUri.META_DATA_LABEL);
27
+ }
28
+ else {
29
+ const match = resource.path.match(fileIconDirectoryRegex);
30
+ if (match) {
31
+ name = cssEscape(match[2].toLowerCase());
32
+ if (match[1]) {
33
+ classes.push(`${cssEscape(match[1].toLowerCase())}-name-dir-icon`); // parent directory
34
+ }
35
+ }
36
+ else {
37
+ name = cssEscape(resource.authority.toLowerCase());
38
+ }
39
+ }
40
+ // Root Folders
41
+ if (fileKind === FileKind.ROOT_FOLDER) {
42
+ classes.push(`${name}-root-name-folder-icon`);
43
+ }
44
+ // Folders
45
+ else if (fileKind === FileKind.FOLDER) {
46
+ classes.push(`${name}-name-folder-icon`);
47
+ }
48
+ // Files
49
+ else {
50
+ // Name & Extension(s)
51
+ if (name) {
52
+ classes.push(`${name}-name-file-icon`);
53
+ classes.push(`name-file-icon`); // extra segment to increase file-name score
54
+ // Avoid doing an explosive combination of extensions for very long filenames
55
+ // (most file systems do not allow files > 255 length) with lots of `.` characters
56
+ // https://github.com/microsoft/vscode/issues/116199
57
+ if (name.length <= 255) {
58
+ const dotSegments = name.split('.');
59
+ for (let i = 1; i < dotSegments.length; i++) {
60
+ classes.push(`${dotSegments.slice(i).join('.')}-ext-file-icon`); // add each combination of all found extensions if more than one
61
+ }
62
+ }
63
+ classes.push(`ext-file-icon`); // extra segment to increase file-ext score
64
+ }
65
+ // Detected Mode
66
+ const detectedLanguageId = detectLanguageId(modelService, languageService, resource);
67
+ if (detectedLanguageId) {
68
+ classes.push(`${cssEscape(detectedLanguageId)}-lang-file-icon`);
69
+ }
70
+ }
71
+ }
72
+ return classes;
73
+ }
74
+ function detectLanguageId(modelService, languageService, resource) {
75
+ if (!resource) {
76
+ return null; // we need a resource at least
77
+ }
78
+ let languageId = null;
79
+ // Data URI: check for encoded metadata
80
+ if (resource.scheme === Schemas.data) {
81
+ const metadata = DataUri.parseMetaData(resource);
82
+ const mime = metadata.get(DataUri.META_DATA_MIME);
83
+ if (mime) {
84
+ languageId = languageService.getLanguageIdByMimeType(mime);
85
+ }
86
+ }
87
+ // Any other URI: check for model if existing
88
+ else {
89
+ const model = modelService.getModel(resource);
90
+ if (model) {
91
+ languageId = model.getLanguageId();
92
+ }
93
+ }
94
+ // only take if the language id is specific (aka no just plain text)
95
+ if (languageId && languageId !== PLAINTEXT_LANGUAGE_ID) {
96
+ return languageId;
97
+ }
98
+ // otherwise fallback to path based detection
99
+ return languageService.guessLanguageIdByFilepathOrFirstLine(resource);
100
+ }
101
+ function cssEscape(str) {
102
+ return str.replace(/[\s]/g, '/'); // HTML class names can not contain certain whitespace characters (https://dom.spec.whatwg.org/#interface-domtokenlist), use / instead, which doesn't exist in file names.
103
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/languageFeatureDebounce.js ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
6
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
8
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ import { doHash } from '../../../base/common/hash.js';
15
+ import { LRUCache } from '../../../base/common/map.js';
16
+ import { clamp, MovingAverage, SlidingWindowAverage } from '../../../base/common/numbers.js';
17
+ import { IEnvironmentService } from '../../../platform/environment/common/environment.js';
18
+ import { registerSingleton } from '../../../platform/instantiation/common/extensions.js';
19
+ import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
20
+ import { ILogService } from '../../../platform/log/common/log.js';
21
+ import { matchesScheme } from '../../../base/common/network.js';
22
+ export const ILanguageFeatureDebounceService = createDecorator('ILanguageFeatureDebounceService');
23
+ var IdentityHash;
24
+ (function (IdentityHash) {
25
+ const _hashes = new WeakMap();
26
+ let pool = 0;
27
+ function of(obj) {
28
+ let value = _hashes.get(obj);
29
+ if (value === undefined) {
30
+ value = ++pool;
31
+ _hashes.set(obj, value);
32
+ }
33
+ return value;
34
+ }
35
+ IdentityHash.of = of;
36
+ })(IdentityHash || (IdentityHash = {}));
37
+ class NullDebounceInformation {
38
+ constructor(_default) {
39
+ this._default = _default;
40
+ }
41
+ get(_model) {
42
+ return this._default;
43
+ }
44
+ update(_model, _value) {
45
+ return this._default;
46
+ }
47
+ default() {
48
+ return this._default;
49
+ }
50
+ }
51
+ class FeatureDebounceInformation {
52
+ constructor(_logService, _name, _registry, _default, _min, _max) {
53
+ this._logService = _logService;
54
+ this._name = _name;
55
+ this._registry = _registry;
56
+ this._default = _default;
57
+ this._min = _min;
58
+ this._max = _max;
59
+ this._cache = new LRUCache(50, 0.7);
60
+ }
61
+ _key(model) {
62
+ return model.id + this._registry.all(model).reduce((hashVal, obj) => doHash(IdentityHash.of(obj), hashVal), 0);
63
+ }
64
+ get(model) {
65
+ const key = this._key(model);
66
+ const avg = this._cache.get(key);
67
+ return avg
68
+ ? clamp(avg.value, this._min, this._max)
69
+ : this.default();
70
+ }
71
+ update(model, value) {
72
+ const key = this._key(model);
73
+ let avg = this._cache.get(key);
74
+ if (!avg) {
75
+ avg = new SlidingWindowAverage(6);
76
+ this._cache.set(key, avg);
77
+ }
78
+ const newValue = clamp(avg.update(value), this._min, this._max);
79
+ if (!matchesScheme(model.uri, 'output')) {
80
+ this._logService.trace(`[DEBOUNCE: ${this._name}] for ${model.uri.toString()} is ${newValue}ms`);
81
+ }
82
+ return newValue;
83
+ }
84
+ _overall() {
85
+ const result = new MovingAverage();
86
+ for (const [, avg] of this._cache) {
87
+ result.update(avg.value);
88
+ }
89
+ return result.value;
90
+ }
91
+ default() {
92
+ const value = (this._overall() | 0) || this._default;
93
+ return clamp(value, this._min, this._max);
94
+ }
95
+ }
96
+ let LanguageFeatureDebounceService = class LanguageFeatureDebounceService {
97
+ constructor(_logService, envService) {
98
+ this._logService = _logService;
99
+ this._data = new Map();
100
+ this._isDev = envService.isExtensionDevelopment || !envService.isBuilt;
101
+ }
102
+ for(feature, name, config) {
103
+ const min = config?.min ?? 50;
104
+ const max = config?.max ?? min ** 2;
105
+ const extra = config?.key ?? undefined;
106
+ const key = `${IdentityHash.of(feature)},${min}${extra ? ',' + extra : ''}`;
107
+ let info = this._data.get(key);
108
+ if (!info) {
109
+ if (this._isDev) {
110
+ this._logService.debug(`[DEBOUNCE: ${name}] is disabled in developed mode`);
111
+ info = new NullDebounceInformation(min * 1.5);
112
+ }
113
+ else {
114
+ info = new FeatureDebounceInformation(this._logService, name, feature, (this._overallAverage() | 0) || (min * 1.5), // default is overall default or derived from min-value
115
+ min, max);
116
+ }
117
+ this._data.set(key, info);
118
+ }
119
+ return info;
120
+ }
121
+ _overallAverage() {
122
+ // Average of all language features. Not a great value but an approximation
123
+ const result = new MovingAverage();
124
+ for (const info of this._data.values()) {
125
+ result.update(info.default());
126
+ }
127
+ return result.value;
128
+ }
129
+ };
130
+ LanguageFeatureDebounceService = __decorate([
131
+ __param(0, ILogService),
132
+ __param(1, IEnvironmentService)
133
+ ], LanguageFeatureDebounceService);
134
+ export { LanguageFeatureDebounceService };
135
+ registerSingleton(ILanguageFeatureDebounceService, LanguageFeatureDebounceService, 1 /* InstantiationType.Delayed */);
node_modules/monaco-editor/esm/vs/editor/common/services/languageFeatures.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
6
+ export const ILanguageFeaturesService = createDecorator('ILanguageFeaturesService');
node_modules/monaco-editor/esm/vs/editor/common/services/languageFeaturesService.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { LanguageFeatureRegistry } from '../languageFeatureRegistry.js';
6
+ import { ILanguageFeaturesService } from './languageFeatures.js';
7
+ import { registerSingleton } from '../../../platform/instantiation/common/extensions.js';
8
+ export class LanguageFeaturesService {
9
+ constructor() {
10
+ this.referenceProvider = new LanguageFeatureRegistry(this._score.bind(this));
11
+ this.renameProvider = new LanguageFeatureRegistry(this._score.bind(this));
12
+ this.newSymbolNamesProvider = new LanguageFeatureRegistry(this._score.bind(this));
13
+ this.codeActionProvider = new LanguageFeatureRegistry(this._score.bind(this));
14
+ this.definitionProvider = new LanguageFeatureRegistry(this._score.bind(this));
15
+ this.typeDefinitionProvider = new LanguageFeatureRegistry(this._score.bind(this));
16
+ this.declarationProvider = new LanguageFeatureRegistry(this._score.bind(this));
17
+ this.implementationProvider = new LanguageFeatureRegistry(this._score.bind(this));
18
+ this.documentSymbolProvider = new LanguageFeatureRegistry(this._score.bind(this));
19
+ this.inlayHintsProvider = new LanguageFeatureRegistry(this._score.bind(this));
20
+ this.colorProvider = new LanguageFeatureRegistry(this._score.bind(this));
21
+ this.codeLensProvider = new LanguageFeatureRegistry(this._score.bind(this));
22
+ this.documentFormattingEditProvider = new LanguageFeatureRegistry(this._score.bind(this));
23
+ this.documentRangeFormattingEditProvider = new LanguageFeatureRegistry(this._score.bind(this));
24
+ this.onTypeFormattingEditProvider = new LanguageFeatureRegistry(this._score.bind(this));
25
+ this.signatureHelpProvider = new LanguageFeatureRegistry(this._score.bind(this));
26
+ this.hoverProvider = new LanguageFeatureRegistry(this._score.bind(this));
27
+ this.documentHighlightProvider = new LanguageFeatureRegistry(this._score.bind(this));
28
+ this.multiDocumentHighlightProvider = new LanguageFeatureRegistry(this._score.bind(this));
29
+ this.selectionRangeProvider = new LanguageFeatureRegistry(this._score.bind(this));
30
+ this.foldingRangeProvider = new LanguageFeatureRegistry(this._score.bind(this));
31
+ this.linkProvider = new LanguageFeatureRegistry(this._score.bind(this));
32
+ this.inlineCompletionsProvider = new LanguageFeatureRegistry(this._score.bind(this));
33
+ this.inlineEditProvider = new LanguageFeatureRegistry(this._score.bind(this));
34
+ this.completionProvider = new LanguageFeatureRegistry(this._score.bind(this));
35
+ this.linkedEditingRangeProvider = new LanguageFeatureRegistry(this._score.bind(this));
36
+ this.documentRangeSemanticTokensProvider = new LanguageFeatureRegistry(this._score.bind(this));
37
+ this.documentSemanticTokensProvider = new LanguageFeatureRegistry(this._score.bind(this));
38
+ this.documentDropEditProvider = new LanguageFeatureRegistry(this._score.bind(this));
39
+ this.documentPasteEditProvider = new LanguageFeatureRegistry(this._score.bind(this));
40
+ }
41
+ _score(uri) {
42
+ return this._notebookTypeResolver?.(uri);
43
+ }
44
+ }
45
+ registerSingleton(ILanguageFeaturesService, LanguageFeaturesService, 1 /* InstantiationType.Delayed */);
node_modules/monaco-editor/esm/vs/editor/common/services/languageService.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { Emitter, Event } from '../../../base/common/event.js';
6
+ import { Disposable } from '../../../base/common/lifecycle.js';
7
+ import { LanguagesRegistry } from './languagesRegistry.js';
8
+ import { firstOrDefault } from '../../../base/common/arrays.js';
9
+ import { TokenizationRegistry } from '../languages.js';
10
+ import { PLAINTEXT_LANGUAGE_ID } from '../languages/modesRegistry.js';
11
+ import { observableFromEvent } from '../../../base/common/observable.js';
12
+ export class LanguageService extends Disposable {
13
+ static { this.instanceCount = 0; }
14
+ constructor(warnOnOverwrite = false) {
15
+ super();
16
+ this._onDidRequestBasicLanguageFeatures = this._register(new Emitter());
17
+ this.onDidRequestBasicLanguageFeatures = this._onDidRequestBasicLanguageFeatures.event;
18
+ this._onDidRequestRichLanguageFeatures = this._register(new Emitter());
19
+ this.onDidRequestRichLanguageFeatures = this._onDidRequestRichLanguageFeatures.event;
20
+ this._onDidChange = this._register(new Emitter({ leakWarningThreshold: 200 /* https://github.com/microsoft/vscode/issues/119968 */ }));
21
+ this.onDidChange = this._onDidChange.event;
22
+ this._requestedBasicLanguages = new Set();
23
+ this._requestedRichLanguages = new Set();
24
+ LanguageService.instanceCount++;
25
+ this._registry = this._register(new LanguagesRegistry(true, warnOnOverwrite));
26
+ this.languageIdCodec = this._registry.languageIdCodec;
27
+ this._register(this._registry.onDidChange(() => this._onDidChange.fire()));
28
+ }
29
+ dispose() {
30
+ LanguageService.instanceCount--;
31
+ super.dispose();
32
+ }
33
+ isRegisteredLanguageId(languageId) {
34
+ return this._registry.isRegisteredLanguageId(languageId);
35
+ }
36
+ getLanguageIdByLanguageName(languageName) {
37
+ return this._registry.getLanguageIdByLanguageName(languageName);
38
+ }
39
+ getLanguageIdByMimeType(mimeType) {
40
+ return this._registry.getLanguageIdByMimeType(mimeType);
41
+ }
42
+ guessLanguageIdByFilepathOrFirstLine(resource, firstLine) {
43
+ const languageIds = this._registry.guessLanguageIdByFilepathOrFirstLine(resource, firstLine);
44
+ return firstOrDefault(languageIds, null);
45
+ }
46
+ createById(languageId) {
47
+ return new LanguageSelection(this.onDidChange, () => {
48
+ return this._createAndGetLanguageIdentifier(languageId);
49
+ });
50
+ }
51
+ createByFilepathOrFirstLine(resource, firstLine) {
52
+ return new LanguageSelection(this.onDidChange, () => {
53
+ const languageId = this.guessLanguageIdByFilepathOrFirstLine(resource, firstLine);
54
+ return this._createAndGetLanguageIdentifier(languageId);
55
+ });
56
+ }
57
+ _createAndGetLanguageIdentifier(languageId) {
58
+ if (!languageId || !this.isRegisteredLanguageId(languageId)) {
59
+ // Fall back to plain text if language is unknown
60
+ languageId = PLAINTEXT_LANGUAGE_ID;
61
+ }
62
+ return languageId;
63
+ }
64
+ requestBasicLanguageFeatures(languageId) {
65
+ if (!this._requestedBasicLanguages.has(languageId)) {
66
+ this._requestedBasicLanguages.add(languageId);
67
+ this._onDidRequestBasicLanguageFeatures.fire(languageId);
68
+ }
69
+ }
70
+ requestRichLanguageFeatures(languageId) {
71
+ if (!this._requestedRichLanguages.has(languageId)) {
72
+ this._requestedRichLanguages.add(languageId);
73
+ // Ensure basic features are requested
74
+ this.requestBasicLanguageFeatures(languageId);
75
+ // Ensure tokenizers are created
76
+ TokenizationRegistry.getOrCreate(languageId);
77
+ this._onDidRequestRichLanguageFeatures.fire(languageId);
78
+ }
79
+ }
80
+ }
81
+ class LanguageSelection {
82
+ constructor(onDidChangeLanguages, selector) {
83
+ this._value = observableFromEvent(this, onDidChangeLanguages, () => selector());
84
+ this.onDidChange = Event.fromObservable(this._value);
85
+ }
86
+ get languageId() {
87
+ return this._value.get();
88
+ }
89
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/languagesAssociations.js ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { parse } from '../../../base/common/glob.js';
6
+ import { Mimes } from '../../../base/common/mime.js';
7
+ import { Schemas } from '../../../base/common/network.js';
8
+ import { basename, posix } from '../../../base/common/path.js';
9
+ import { DataUri } from '../../../base/common/resources.js';
10
+ import { startsWithUTF8BOM } from '../../../base/common/strings.js';
11
+ import { PLAINTEXT_LANGUAGE_ID } from '../languages/modesRegistry.js';
12
+ let registeredAssociations = [];
13
+ let nonUserRegisteredAssociations = [];
14
+ let userRegisteredAssociations = [];
15
+ /**
16
+ * Associate a language to the registry (platform).
17
+ * * **NOTE**: This association will lose over associations registered using `registerConfiguredLanguageAssociation`.
18
+ * * **NOTE**: Use `clearPlatformLanguageAssociations` to remove all associations registered using this function.
19
+ */
20
+ export function registerPlatformLanguageAssociation(association, warnOnOverwrite = false) {
21
+ _registerLanguageAssociation(association, false, warnOnOverwrite);
22
+ }
23
+ function _registerLanguageAssociation(association, userConfigured, warnOnOverwrite) {
24
+ // Register
25
+ const associationItem = toLanguageAssociationItem(association, userConfigured);
26
+ registeredAssociations.push(associationItem);
27
+ if (!associationItem.userConfigured) {
28
+ nonUserRegisteredAssociations.push(associationItem);
29
+ }
30
+ else {
31
+ userRegisteredAssociations.push(associationItem);
32
+ }
33
+ // Check for conflicts unless this is a user configured association
34
+ if (warnOnOverwrite && !associationItem.userConfigured) {
35
+ registeredAssociations.forEach(a => {
36
+ if (a.mime === associationItem.mime || a.userConfigured) {
37
+ return; // same mime or userConfigured is ok
38
+ }
39
+ if (associationItem.extension && a.extension === associationItem.extension) {
40
+ console.warn(`Overwriting extension <<${associationItem.extension}>> to now point to mime <<${associationItem.mime}>>`);
41
+ }
42
+ if (associationItem.filename && a.filename === associationItem.filename) {
43
+ console.warn(`Overwriting filename <<${associationItem.filename}>> to now point to mime <<${associationItem.mime}>>`);
44
+ }
45
+ if (associationItem.filepattern && a.filepattern === associationItem.filepattern) {
46
+ console.warn(`Overwriting filepattern <<${associationItem.filepattern}>> to now point to mime <<${associationItem.mime}>>`);
47
+ }
48
+ if (associationItem.firstline && a.firstline === associationItem.firstline) {
49
+ console.warn(`Overwriting firstline <<${associationItem.firstline}>> to now point to mime <<${associationItem.mime}>>`);
50
+ }
51
+ });
52
+ }
53
+ }
54
+ function toLanguageAssociationItem(association, userConfigured) {
55
+ return {
56
+ id: association.id,
57
+ mime: association.mime,
58
+ filename: association.filename,
59
+ extension: association.extension,
60
+ filepattern: association.filepattern,
61
+ firstline: association.firstline,
62
+ userConfigured: userConfigured,
63
+ filenameLowercase: association.filename ? association.filename.toLowerCase() : undefined,
64
+ extensionLowercase: association.extension ? association.extension.toLowerCase() : undefined,
65
+ filepatternLowercase: association.filepattern ? parse(association.filepattern.toLowerCase()) : undefined,
66
+ filepatternOnPath: association.filepattern ? association.filepattern.indexOf(posix.sep) >= 0 : false
67
+ };
68
+ }
69
+ /**
70
+ * Clear language associations from the registry (platform).
71
+ */
72
+ export function clearPlatformLanguageAssociations() {
73
+ registeredAssociations = registeredAssociations.filter(a => a.userConfigured);
74
+ nonUserRegisteredAssociations = [];
75
+ }
76
+ /**
77
+ * @see `getMimeTypes`
78
+ */
79
+ export function getLanguageIds(resource, firstLine) {
80
+ return getAssociations(resource, firstLine).map(item => item.id);
81
+ }
82
+ function getAssociations(resource, firstLine) {
83
+ let path;
84
+ if (resource) {
85
+ switch (resource.scheme) {
86
+ case Schemas.file:
87
+ path = resource.fsPath;
88
+ break;
89
+ case Schemas.data: {
90
+ const metadata = DataUri.parseMetaData(resource);
91
+ path = metadata.get(DataUri.META_DATA_LABEL);
92
+ break;
93
+ }
94
+ case Schemas.vscodeNotebookCell:
95
+ // File path not relevant for language detection of cell
96
+ path = undefined;
97
+ break;
98
+ default:
99
+ path = resource.path;
100
+ }
101
+ }
102
+ if (!path) {
103
+ return [{ id: 'unknown', mime: Mimes.unknown }];
104
+ }
105
+ path = path.toLowerCase();
106
+ const filename = basename(path);
107
+ // 1.) User configured mappings have highest priority
108
+ const configuredLanguage = getAssociationByPath(path, filename, userRegisteredAssociations);
109
+ if (configuredLanguage) {
110
+ return [configuredLanguage, { id: PLAINTEXT_LANGUAGE_ID, mime: Mimes.text }];
111
+ }
112
+ // 2.) Registered mappings have middle priority
113
+ const registeredLanguage = getAssociationByPath(path, filename, nonUserRegisteredAssociations);
114
+ if (registeredLanguage) {
115
+ return [registeredLanguage, { id: PLAINTEXT_LANGUAGE_ID, mime: Mimes.text }];
116
+ }
117
+ // 3.) Firstline has lowest priority
118
+ if (firstLine) {
119
+ const firstlineLanguage = getAssociationByFirstline(firstLine);
120
+ if (firstlineLanguage) {
121
+ return [firstlineLanguage, { id: PLAINTEXT_LANGUAGE_ID, mime: Mimes.text }];
122
+ }
123
+ }
124
+ return [{ id: 'unknown', mime: Mimes.unknown }];
125
+ }
126
+ function getAssociationByPath(path, filename, associations) {
127
+ let filenameMatch = undefined;
128
+ let patternMatch = undefined;
129
+ let extensionMatch = undefined;
130
+ // We want to prioritize associations based on the order they are registered so that the last registered
131
+ // association wins over all other. This is for https://github.com/microsoft/vscode/issues/20074
132
+ for (let i = associations.length - 1; i >= 0; i--) {
133
+ const association = associations[i];
134
+ // First exact name match
135
+ if (filename === association.filenameLowercase) {
136
+ filenameMatch = association;
137
+ break; // take it!
138
+ }
139
+ // Longest pattern match
140
+ if (association.filepattern) {
141
+ if (!patternMatch || association.filepattern.length > patternMatch.filepattern.length) {
142
+ const target = association.filepatternOnPath ? path : filename; // match on full path if pattern contains path separator
143
+ if (association.filepatternLowercase?.(target)) {
144
+ patternMatch = association;
145
+ }
146
+ }
147
+ }
148
+ // Longest extension match
149
+ if (association.extension) {
150
+ if (!extensionMatch || association.extension.length > extensionMatch.extension.length) {
151
+ if (filename.endsWith(association.extensionLowercase)) {
152
+ extensionMatch = association;
153
+ }
154
+ }
155
+ }
156
+ }
157
+ // 1.) Exact name match has second highest priority
158
+ if (filenameMatch) {
159
+ return filenameMatch;
160
+ }
161
+ // 2.) Match on pattern
162
+ if (patternMatch) {
163
+ return patternMatch;
164
+ }
165
+ // 3.) Match on extension comes next
166
+ if (extensionMatch) {
167
+ return extensionMatch;
168
+ }
169
+ return undefined;
170
+ }
171
+ function getAssociationByFirstline(firstLine) {
172
+ if (startsWithUTF8BOM(firstLine)) {
173
+ firstLine = firstLine.substr(1);
174
+ }
175
+ if (firstLine.length > 0) {
176
+ // We want to prioritize associations based on the order they are registered so that the last registered
177
+ // association wins over all other. This is for https://github.com/microsoft/vscode/issues/20074
178
+ for (let i = registeredAssociations.length - 1; i >= 0; i--) {
179
+ const association = registeredAssociations[i];
180
+ if (!association.firstline) {
181
+ continue;
182
+ }
183
+ const matches = firstLine.match(association.firstline);
184
+ if (matches && matches.length > 0) {
185
+ return association;
186
+ }
187
+ }
188
+ }
189
+ return undefined;
190
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/languagesRegistry.js ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { Emitter } from '../../../base/common/event.js';
6
+ import { Disposable } from '../../../base/common/lifecycle.js';
7
+ import { regExpLeadsToEndlessLoop } from '../../../base/common/strings.js';
8
+ import { clearPlatformLanguageAssociations, getLanguageIds, registerPlatformLanguageAssociation } from './languagesAssociations.js';
9
+ import { ModesRegistry, PLAINTEXT_LANGUAGE_ID } from '../languages/modesRegistry.js';
10
+ import { Extensions } from '../../../platform/configuration/common/configurationRegistry.js';
11
+ import { Registry } from '../../../platform/registry/common/platform.js';
12
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
13
+ const NULL_LANGUAGE_ID = 'vs.editor.nullLanguage';
14
+ export class LanguageIdCodec {
15
+ constructor() {
16
+ this._languageIdToLanguage = [];
17
+ this._languageToLanguageId = new Map();
18
+ this._register(NULL_LANGUAGE_ID, 0 /* LanguageId.Null */);
19
+ this._register(PLAINTEXT_LANGUAGE_ID, 1 /* LanguageId.PlainText */);
20
+ this._nextLanguageId = 2;
21
+ }
22
+ _register(language, languageId) {
23
+ this._languageIdToLanguage[languageId] = language;
24
+ this._languageToLanguageId.set(language, languageId);
25
+ }
26
+ register(language) {
27
+ if (this._languageToLanguageId.has(language)) {
28
+ return;
29
+ }
30
+ const languageId = this._nextLanguageId++;
31
+ this._register(language, languageId);
32
+ }
33
+ encodeLanguageId(languageId) {
34
+ return this._languageToLanguageId.get(languageId) || 0 /* LanguageId.Null */;
35
+ }
36
+ decodeLanguageId(languageId) {
37
+ return this._languageIdToLanguage[languageId] || NULL_LANGUAGE_ID;
38
+ }
39
+ }
40
+ export class LanguagesRegistry extends Disposable {
41
+ static { this.instanceCount = 0; }
42
+ constructor(useModesRegistry = true, warnOnOverwrite = false) {
43
+ super();
44
+ this._onDidChange = this._register(new Emitter());
45
+ this.onDidChange = this._onDidChange.event;
46
+ LanguagesRegistry.instanceCount++;
47
+ this._warnOnOverwrite = warnOnOverwrite;
48
+ this.languageIdCodec = new LanguageIdCodec();
49
+ this._dynamicLanguages = [];
50
+ this._languages = {};
51
+ this._mimeTypesMap = {};
52
+ this._nameMap = {};
53
+ this._lowercaseNameMap = {};
54
+ if (useModesRegistry) {
55
+ this._initializeFromRegistry();
56
+ this._register(ModesRegistry.onDidChangeLanguages((m) => {
57
+ this._initializeFromRegistry();
58
+ }));
59
+ }
60
+ }
61
+ dispose() {
62
+ LanguagesRegistry.instanceCount--;
63
+ super.dispose();
64
+ }
65
+ _initializeFromRegistry() {
66
+ this._languages = {};
67
+ this._mimeTypesMap = {};
68
+ this._nameMap = {};
69
+ this._lowercaseNameMap = {};
70
+ clearPlatformLanguageAssociations();
71
+ const desc = [].concat(ModesRegistry.getLanguages()).concat(this._dynamicLanguages);
72
+ this._registerLanguages(desc);
73
+ }
74
+ _registerLanguages(desc) {
75
+ for (const d of desc) {
76
+ this._registerLanguage(d);
77
+ }
78
+ // Rebuild fast path maps
79
+ this._mimeTypesMap = {};
80
+ this._nameMap = {};
81
+ this._lowercaseNameMap = {};
82
+ Object.keys(this._languages).forEach((langId) => {
83
+ const language = this._languages[langId];
84
+ if (language.name) {
85
+ this._nameMap[language.name] = language.identifier;
86
+ }
87
+ language.aliases.forEach((alias) => {
88
+ this._lowercaseNameMap[alias.toLowerCase()] = language.identifier;
89
+ });
90
+ language.mimetypes.forEach((mimetype) => {
91
+ this._mimeTypesMap[mimetype] = language.identifier;
92
+ });
93
+ });
94
+ Registry.as(Extensions.Configuration).registerOverrideIdentifiers(this.getRegisteredLanguageIds());
95
+ this._onDidChange.fire();
96
+ }
97
+ _registerLanguage(lang) {
98
+ const langId = lang.id;
99
+ let resolvedLanguage;
100
+ if (hasOwnProperty.call(this._languages, langId)) {
101
+ resolvedLanguage = this._languages[langId];
102
+ }
103
+ else {
104
+ this.languageIdCodec.register(langId);
105
+ resolvedLanguage = {
106
+ identifier: langId,
107
+ name: null,
108
+ mimetypes: [],
109
+ aliases: [],
110
+ extensions: [],
111
+ filenames: [],
112
+ configurationFiles: [],
113
+ icons: []
114
+ };
115
+ this._languages[langId] = resolvedLanguage;
116
+ }
117
+ this._mergeLanguage(resolvedLanguage, lang);
118
+ }
119
+ _mergeLanguage(resolvedLanguage, lang) {
120
+ const langId = lang.id;
121
+ let primaryMime = null;
122
+ if (Array.isArray(lang.mimetypes) && lang.mimetypes.length > 0) {
123
+ resolvedLanguage.mimetypes.push(...lang.mimetypes);
124
+ primaryMime = lang.mimetypes[0];
125
+ }
126
+ if (!primaryMime) {
127
+ primaryMime = `text/x-${langId}`;
128
+ resolvedLanguage.mimetypes.push(primaryMime);
129
+ }
130
+ if (Array.isArray(lang.extensions)) {
131
+ if (lang.configuration) {
132
+ // insert first as this appears to be the 'primary' language definition
133
+ resolvedLanguage.extensions = lang.extensions.concat(resolvedLanguage.extensions);
134
+ }
135
+ else {
136
+ resolvedLanguage.extensions = resolvedLanguage.extensions.concat(lang.extensions);
137
+ }
138
+ for (const extension of lang.extensions) {
139
+ registerPlatformLanguageAssociation({ id: langId, mime: primaryMime, extension: extension }, this._warnOnOverwrite);
140
+ }
141
+ }
142
+ if (Array.isArray(lang.filenames)) {
143
+ for (const filename of lang.filenames) {
144
+ registerPlatformLanguageAssociation({ id: langId, mime: primaryMime, filename: filename }, this._warnOnOverwrite);
145
+ resolvedLanguage.filenames.push(filename);
146
+ }
147
+ }
148
+ if (Array.isArray(lang.filenamePatterns)) {
149
+ for (const filenamePattern of lang.filenamePatterns) {
150
+ registerPlatformLanguageAssociation({ id: langId, mime: primaryMime, filepattern: filenamePattern }, this._warnOnOverwrite);
151
+ }
152
+ }
153
+ if (typeof lang.firstLine === 'string' && lang.firstLine.length > 0) {
154
+ let firstLineRegexStr = lang.firstLine;
155
+ if (firstLineRegexStr.charAt(0) !== '^') {
156
+ firstLineRegexStr = '^' + firstLineRegexStr;
157
+ }
158
+ try {
159
+ const firstLineRegex = new RegExp(firstLineRegexStr);
160
+ if (!regExpLeadsToEndlessLoop(firstLineRegex)) {
161
+ registerPlatformLanguageAssociation({ id: langId, mime: primaryMime, firstline: firstLineRegex }, this._warnOnOverwrite);
162
+ }
163
+ }
164
+ catch (err) {
165
+ // Most likely, the regex was bad
166
+ console.warn(`[${lang.id}]: Invalid regular expression \`${firstLineRegexStr}\`: `, err);
167
+ }
168
+ }
169
+ resolvedLanguage.aliases.push(langId);
170
+ let langAliases = null;
171
+ if (typeof lang.aliases !== 'undefined' && Array.isArray(lang.aliases)) {
172
+ if (lang.aliases.length === 0) {
173
+ // signal that this language should not get a name
174
+ langAliases = [null];
175
+ }
176
+ else {
177
+ langAliases = lang.aliases;
178
+ }
179
+ }
180
+ if (langAliases !== null) {
181
+ for (const langAlias of langAliases) {
182
+ if (!langAlias || langAlias.length === 0) {
183
+ continue;
184
+ }
185
+ resolvedLanguage.aliases.push(langAlias);
186
+ }
187
+ }
188
+ const containsAliases = (langAliases !== null && langAliases.length > 0);
189
+ if (containsAliases && langAliases[0] === null) {
190
+ // signal that this language should not get a name
191
+ }
192
+ else {
193
+ const bestName = (containsAliases ? langAliases[0] : null) || langId;
194
+ if (containsAliases || !resolvedLanguage.name) {
195
+ resolvedLanguage.name = bestName;
196
+ }
197
+ }
198
+ if (lang.configuration) {
199
+ resolvedLanguage.configurationFiles.push(lang.configuration);
200
+ }
201
+ if (lang.icon) {
202
+ resolvedLanguage.icons.push(lang.icon);
203
+ }
204
+ }
205
+ isRegisteredLanguageId(languageId) {
206
+ if (!languageId) {
207
+ return false;
208
+ }
209
+ return hasOwnProperty.call(this._languages, languageId);
210
+ }
211
+ getRegisteredLanguageIds() {
212
+ return Object.keys(this._languages);
213
+ }
214
+ getLanguageIdByLanguageName(languageName) {
215
+ const languageNameLower = languageName.toLowerCase();
216
+ if (!hasOwnProperty.call(this._lowercaseNameMap, languageNameLower)) {
217
+ return null;
218
+ }
219
+ return this._lowercaseNameMap[languageNameLower];
220
+ }
221
+ getLanguageIdByMimeType(mimeType) {
222
+ if (!mimeType) {
223
+ return null;
224
+ }
225
+ if (hasOwnProperty.call(this._mimeTypesMap, mimeType)) {
226
+ return this._mimeTypesMap[mimeType];
227
+ }
228
+ return null;
229
+ }
230
+ guessLanguageIdByFilepathOrFirstLine(resource, firstLine) {
231
+ if (!resource && !firstLine) {
232
+ return [];
233
+ }
234
+ return getLanguageIds(resource, firstLine);
235
+ }
236
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/markerDecorations.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
6
+ export const IMarkerDecorationsService = createDecorator('markerDecorationsService');
node_modules/monaco-editor/esm/vs/editor/common/services/markerDecorationsService.js ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
6
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
8
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ import { IMarkerService, MarkerSeverity } from '../../../platform/markers/common/markers.js';
15
+ import { Disposable, toDisposable } from '../../../base/common/lifecycle.js';
16
+ import { OverviewRulerLane } from '../model.js';
17
+ import { themeColorFromId } from '../../../platform/theme/common/themeService.js';
18
+ import { overviewRulerWarning, overviewRulerInfo, overviewRulerError } from '../core/editorColorRegistry.js';
19
+ import { IModelService } from './model.js';
20
+ import { Range } from '../core/range.js';
21
+ import { Schemas } from '../../../base/common/network.js';
22
+ import { Emitter } from '../../../base/common/event.js';
23
+ import { minimapInfo, minimapWarning, minimapError } from '../../../platform/theme/common/colorRegistry.js';
24
+ import { BidirectionalMap, ResourceMap } from '../../../base/common/map.js';
25
+ import { diffSets } from '../../../base/common/collections.js';
26
+ let MarkerDecorationsService = class MarkerDecorationsService extends Disposable {
27
+ constructor(modelService, _markerService) {
28
+ super();
29
+ this._markerService = _markerService;
30
+ this._onDidChangeMarker = this._register(new Emitter());
31
+ this._markerDecorations = new ResourceMap();
32
+ modelService.getModels().forEach(model => this._onModelAdded(model));
33
+ this._register(modelService.onModelAdded(this._onModelAdded, this));
34
+ this._register(modelService.onModelRemoved(this._onModelRemoved, this));
35
+ this._register(this._markerService.onMarkerChanged(this._handleMarkerChange, this));
36
+ }
37
+ dispose() {
38
+ super.dispose();
39
+ this._markerDecorations.forEach(value => value.dispose());
40
+ this._markerDecorations.clear();
41
+ }
42
+ getMarker(uri, decoration) {
43
+ const markerDecorations = this._markerDecorations.get(uri);
44
+ return markerDecorations ? (markerDecorations.getMarker(decoration) || null) : null;
45
+ }
46
+ _handleMarkerChange(changedResources) {
47
+ changedResources.forEach((resource) => {
48
+ const markerDecorations = this._markerDecorations.get(resource);
49
+ if (markerDecorations) {
50
+ this._updateDecorations(markerDecorations);
51
+ }
52
+ });
53
+ }
54
+ _onModelAdded(model) {
55
+ const markerDecorations = new MarkerDecorations(model);
56
+ this._markerDecorations.set(model.uri, markerDecorations);
57
+ this._updateDecorations(markerDecorations);
58
+ }
59
+ _onModelRemoved(model) {
60
+ const markerDecorations = this._markerDecorations.get(model.uri);
61
+ if (markerDecorations) {
62
+ markerDecorations.dispose();
63
+ this._markerDecorations.delete(model.uri);
64
+ }
65
+ // clean up markers for internal, transient models
66
+ if (model.uri.scheme === Schemas.inMemory
67
+ || model.uri.scheme === Schemas.internal
68
+ || model.uri.scheme === Schemas.vscode) {
69
+ this._markerService?.read({ resource: model.uri }).map(marker => marker.owner).forEach(owner => this._markerService.remove(owner, [model.uri]));
70
+ }
71
+ }
72
+ _updateDecorations(markerDecorations) {
73
+ // Limit to the first 500 errors/warnings
74
+ const markers = this._markerService.read({ resource: markerDecorations.model.uri, take: 500 });
75
+ if (markerDecorations.update(markers)) {
76
+ this._onDidChangeMarker.fire(markerDecorations.model);
77
+ }
78
+ }
79
+ };
80
+ MarkerDecorationsService = __decorate([
81
+ __param(0, IModelService),
82
+ __param(1, IMarkerService)
83
+ ], MarkerDecorationsService);
84
+ export { MarkerDecorationsService };
85
+ class MarkerDecorations extends Disposable {
86
+ constructor(model) {
87
+ super();
88
+ this.model = model;
89
+ this._map = new BidirectionalMap();
90
+ this._register(toDisposable(() => {
91
+ this.model.deltaDecorations([...this._map.values()], []);
92
+ this._map.clear();
93
+ }));
94
+ }
95
+ update(markers) {
96
+ // We use the fact that marker instances are not recreated when different owners
97
+ // update. So we can compare references to find out what changed since the last update.
98
+ const { added, removed } = diffSets(new Set(this._map.keys()), new Set(markers));
99
+ if (added.length === 0 && removed.length === 0) {
100
+ return false;
101
+ }
102
+ const oldIds = removed.map(marker => this._map.get(marker));
103
+ const newDecorations = added.map(marker => {
104
+ return {
105
+ range: this._createDecorationRange(this.model, marker),
106
+ options: this._createDecorationOption(marker)
107
+ };
108
+ });
109
+ const ids = this.model.deltaDecorations(oldIds, newDecorations);
110
+ for (const removedMarker of removed) {
111
+ this._map.delete(removedMarker);
112
+ }
113
+ for (let index = 0; index < ids.length; index++) {
114
+ this._map.set(added[index], ids[index]);
115
+ }
116
+ return true;
117
+ }
118
+ getMarker(decoration) {
119
+ return this._map.getKey(decoration.id);
120
+ }
121
+ _createDecorationRange(model, rawMarker) {
122
+ let ret = Range.lift(rawMarker);
123
+ if (rawMarker.severity === MarkerSeverity.Hint && !this._hasMarkerTag(rawMarker, 1 /* MarkerTag.Unnecessary */) && !this._hasMarkerTag(rawMarker, 2 /* MarkerTag.Deprecated */)) {
124
+ // * never render hints on multiple lines
125
+ // * make enough space for three dots
126
+ ret = ret.setEndPosition(ret.startLineNumber, ret.startColumn + 2);
127
+ }
128
+ ret = model.validateRange(ret);
129
+ if (ret.isEmpty()) {
130
+ const maxColumn = model.getLineLastNonWhitespaceColumn(ret.startLineNumber) ||
131
+ model.getLineMaxColumn(ret.startLineNumber);
132
+ if (maxColumn === 1 || ret.endColumn >= maxColumn) {
133
+ // empty line or behind eol
134
+ // keep the range as is, it will be rendered 1ch wide
135
+ return ret;
136
+ }
137
+ const word = model.getWordAtPosition(ret.getStartPosition());
138
+ if (word) {
139
+ ret = new Range(ret.startLineNumber, word.startColumn, ret.endLineNumber, word.endColumn);
140
+ }
141
+ }
142
+ else if (rawMarker.endColumn === Number.MAX_VALUE && rawMarker.startColumn === 1 && ret.startLineNumber === ret.endLineNumber) {
143
+ const minColumn = model.getLineFirstNonWhitespaceColumn(rawMarker.startLineNumber);
144
+ if (minColumn < ret.endColumn) {
145
+ ret = new Range(ret.startLineNumber, minColumn, ret.endLineNumber, ret.endColumn);
146
+ rawMarker.startColumn = minColumn;
147
+ }
148
+ }
149
+ return ret;
150
+ }
151
+ _createDecorationOption(marker) {
152
+ let className;
153
+ let color = undefined;
154
+ let zIndex;
155
+ let inlineClassName = undefined;
156
+ let minimap;
157
+ switch (marker.severity) {
158
+ case MarkerSeverity.Hint:
159
+ if (this._hasMarkerTag(marker, 2 /* MarkerTag.Deprecated */)) {
160
+ className = undefined;
161
+ }
162
+ else if (this._hasMarkerTag(marker, 1 /* MarkerTag.Unnecessary */)) {
163
+ className = "squiggly-unnecessary" /* ClassName.EditorUnnecessaryDecoration */;
164
+ }
165
+ else {
166
+ className = "squiggly-hint" /* ClassName.EditorHintDecoration */;
167
+ }
168
+ zIndex = 0;
169
+ break;
170
+ case MarkerSeverity.Info:
171
+ className = "squiggly-info" /* ClassName.EditorInfoDecoration */;
172
+ color = themeColorFromId(overviewRulerInfo);
173
+ zIndex = 10;
174
+ minimap = {
175
+ color: themeColorFromId(minimapInfo),
176
+ position: 1 /* MinimapPosition.Inline */
177
+ };
178
+ break;
179
+ case MarkerSeverity.Warning:
180
+ className = "squiggly-warning" /* ClassName.EditorWarningDecoration */;
181
+ color = themeColorFromId(overviewRulerWarning);
182
+ zIndex = 20;
183
+ minimap = {
184
+ color: themeColorFromId(minimapWarning),
185
+ position: 1 /* MinimapPosition.Inline */
186
+ };
187
+ break;
188
+ case MarkerSeverity.Error:
189
+ default:
190
+ className = "squiggly-error" /* ClassName.EditorErrorDecoration */;
191
+ color = themeColorFromId(overviewRulerError);
192
+ zIndex = 30;
193
+ minimap = {
194
+ color: themeColorFromId(minimapError),
195
+ position: 1 /* MinimapPosition.Inline */
196
+ };
197
+ break;
198
+ }
199
+ if (marker.tags) {
200
+ if (marker.tags.indexOf(1 /* MarkerTag.Unnecessary */) !== -1) {
201
+ inlineClassName = "squiggly-inline-unnecessary" /* ClassName.EditorUnnecessaryInlineDecoration */;
202
+ }
203
+ if (marker.tags.indexOf(2 /* MarkerTag.Deprecated */) !== -1) {
204
+ inlineClassName = "squiggly-inline-deprecated" /* ClassName.EditorDeprecatedInlineDecoration */;
205
+ }
206
+ }
207
+ return {
208
+ description: 'marker-decoration',
209
+ stickiness: 1 /* TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */,
210
+ className,
211
+ showIfCollapsed: true,
212
+ overviewRuler: {
213
+ color,
214
+ position: OverviewRulerLane.Right
215
+ },
216
+ minimap,
217
+ zIndex,
218
+ inlineClassName,
219
+ };
220
+ }
221
+ _hasMarkerTag(marker, tag) {
222
+ if (marker.tags) {
223
+ return marker.tags.indexOf(tag) >= 0;
224
+ }
225
+ return false;
226
+ }
227
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/model.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
6
+ export const IModelService = createDecorator('modelService');
node_modules/monaco-editor/esm/vs/editor/common/services/modelService.js ADDED
@@ -0,0 +1,418 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
6
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
8
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var ModelService_1;
15
+ import { Emitter } from '../../../base/common/event.js';
16
+ import { Disposable, DisposableStore } from '../../../base/common/lifecycle.js';
17
+ import * as platform from '../../../base/common/platform.js';
18
+ import { TextModel } from '../model/textModel.js';
19
+ import { EDITOR_MODEL_DEFAULTS } from '../core/textModelDefaults.js';
20
+ import { PLAINTEXT_LANGUAGE_ID } from '../languages/modesRegistry.js';
21
+ import { ITextResourcePropertiesService } from './textResourceConfiguration.js';
22
+ import { IConfigurationService } from '../../../platform/configuration/common/configuration.js';
23
+ import { IUndoRedoService } from '../../../platform/undoRedo/common/undoRedo.js';
24
+ import { StringSHA1 } from '../../../base/common/hash.js';
25
+ import { isEditStackElement } from '../model/editStack.js';
26
+ import { Schemas } from '../../../base/common/network.js';
27
+ import { equals } from '../../../base/common/objects.js';
28
+ import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js';
29
+ function MODEL_ID(resource) {
30
+ return resource.toString();
31
+ }
32
+ class ModelData {
33
+ constructor(model, onWillDispose, onDidChangeLanguage) {
34
+ this.model = model;
35
+ this._modelEventListeners = new DisposableStore();
36
+ this.model = model;
37
+ this._modelEventListeners.add(model.onWillDispose(() => onWillDispose(model)));
38
+ this._modelEventListeners.add(model.onDidChangeLanguage((e) => onDidChangeLanguage(model, e)));
39
+ }
40
+ dispose() {
41
+ this._modelEventListeners.dispose();
42
+ }
43
+ }
44
+ const DEFAULT_EOL = (platform.isLinux || platform.isMacintosh) ? 1 /* DefaultEndOfLine.LF */ : 2 /* DefaultEndOfLine.CRLF */;
45
+ class DisposedModelInfo {
46
+ constructor(uri, initialUndoRedoSnapshot, time, sharesUndoRedoStack, heapSize, sha1, versionId, alternativeVersionId) {
47
+ this.uri = uri;
48
+ this.initialUndoRedoSnapshot = initialUndoRedoSnapshot;
49
+ this.time = time;
50
+ this.sharesUndoRedoStack = sharesUndoRedoStack;
51
+ this.heapSize = heapSize;
52
+ this.sha1 = sha1;
53
+ this.versionId = versionId;
54
+ this.alternativeVersionId = alternativeVersionId;
55
+ }
56
+ }
57
+ let ModelService = class ModelService extends Disposable {
58
+ static { ModelService_1 = this; }
59
+ static { this.MAX_MEMORY_FOR_CLOSED_FILES_UNDO_STACK = 20 * 1024 * 1024; }
60
+ constructor(_configurationService, _resourcePropertiesService, _undoRedoService, _instantiationService) {
61
+ super();
62
+ this._configurationService = _configurationService;
63
+ this._resourcePropertiesService = _resourcePropertiesService;
64
+ this._undoRedoService = _undoRedoService;
65
+ this._instantiationService = _instantiationService;
66
+ this._onModelAdded = this._register(new Emitter());
67
+ this.onModelAdded = this._onModelAdded.event;
68
+ this._onModelRemoved = this._register(new Emitter());
69
+ this.onModelRemoved = this._onModelRemoved.event;
70
+ this._onModelModeChanged = this._register(new Emitter());
71
+ this.onModelLanguageChanged = this._onModelModeChanged.event;
72
+ this._modelCreationOptionsByLanguageAndResource = Object.create(null);
73
+ this._models = {};
74
+ this._disposedModels = new Map();
75
+ this._disposedModelsHeapSize = 0;
76
+ this._register(this._configurationService.onDidChangeConfiguration(e => this._updateModelOptions(e)));
77
+ this._updateModelOptions(undefined);
78
+ }
79
+ static _readModelOptions(config, isForSimpleWidget) {
80
+ let tabSize = EDITOR_MODEL_DEFAULTS.tabSize;
81
+ if (config.editor && typeof config.editor.tabSize !== 'undefined') {
82
+ const parsedTabSize = parseInt(config.editor.tabSize, 10);
83
+ if (!isNaN(parsedTabSize)) {
84
+ tabSize = parsedTabSize;
85
+ }
86
+ if (tabSize < 1) {
87
+ tabSize = 1;
88
+ }
89
+ }
90
+ let indentSize = 'tabSize';
91
+ if (config.editor && typeof config.editor.indentSize !== 'undefined' && config.editor.indentSize !== 'tabSize') {
92
+ const parsedIndentSize = parseInt(config.editor.indentSize, 10);
93
+ if (!isNaN(parsedIndentSize)) {
94
+ indentSize = Math.max(parsedIndentSize, 1);
95
+ }
96
+ }
97
+ let insertSpaces = EDITOR_MODEL_DEFAULTS.insertSpaces;
98
+ if (config.editor && typeof config.editor.insertSpaces !== 'undefined') {
99
+ insertSpaces = (config.editor.insertSpaces === 'false' ? false : Boolean(config.editor.insertSpaces));
100
+ }
101
+ let newDefaultEOL = DEFAULT_EOL;
102
+ const eol = config.eol;
103
+ if (eol === '\r\n') {
104
+ newDefaultEOL = 2 /* DefaultEndOfLine.CRLF */;
105
+ }
106
+ else if (eol === '\n') {
107
+ newDefaultEOL = 1 /* DefaultEndOfLine.LF */;
108
+ }
109
+ let trimAutoWhitespace = EDITOR_MODEL_DEFAULTS.trimAutoWhitespace;
110
+ if (config.editor && typeof config.editor.trimAutoWhitespace !== 'undefined') {
111
+ trimAutoWhitespace = (config.editor.trimAutoWhitespace === 'false' ? false : Boolean(config.editor.trimAutoWhitespace));
112
+ }
113
+ let detectIndentation = EDITOR_MODEL_DEFAULTS.detectIndentation;
114
+ if (config.editor && typeof config.editor.detectIndentation !== 'undefined') {
115
+ detectIndentation = (config.editor.detectIndentation === 'false' ? false : Boolean(config.editor.detectIndentation));
116
+ }
117
+ let largeFileOptimizations = EDITOR_MODEL_DEFAULTS.largeFileOptimizations;
118
+ if (config.editor && typeof config.editor.largeFileOptimizations !== 'undefined') {
119
+ largeFileOptimizations = (config.editor.largeFileOptimizations === 'false' ? false : Boolean(config.editor.largeFileOptimizations));
120
+ }
121
+ let bracketPairColorizationOptions = EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions;
122
+ if (config.editor?.bracketPairColorization && typeof config.editor.bracketPairColorization === 'object') {
123
+ bracketPairColorizationOptions = {
124
+ enabled: !!config.editor.bracketPairColorization.enabled,
125
+ independentColorPoolPerBracketType: !!config.editor.bracketPairColorization.independentColorPoolPerBracketType
126
+ };
127
+ }
128
+ return {
129
+ isForSimpleWidget: isForSimpleWidget,
130
+ tabSize: tabSize,
131
+ indentSize: indentSize,
132
+ insertSpaces: insertSpaces,
133
+ detectIndentation: detectIndentation,
134
+ defaultEOL: newDefaultEOL,
135
+ trimAutoWhitespace: trimAutoWhitespace,
136
+ largeFileOptimizations: largeFileOptimizations,
137
+ bracketPairColorizationOptions
138
+ };
139
+ }
140
+ _getEOL(resource, language) {
141
+ if (resource) {
142
+ return this._resourcePropertiesService.getEOL(resource, language);
143
+ }
144
+ const eol = this._configurationService.getValue('files.eol', { overrideIdentifier: language });
145
+ if (eol && typeof eol === 'string' && eol !== 'auto') {
146
+ return eol;
147
+ }
148
+ return platform.OS === 3 /* platform.OperatingSystem.Linux */ || platform.OS === 2 /* platform.OperatingSystem.Macintosh */ ? '\n' : '\r\n';
149
+ }
150
+ _shouldRestoreUndoStack() {
151
+ const result = this._configurationService.getValue('files.restoreUndoStack');
152
+ if (typeof result === 'boolean') {
153
+ return result;
154
+ }
155
+ return true;
156
+ }
157
+ getCreationOptions(languageIdOrSelection, resource, isForSimpleWidget) {
158
+ const language = (typeof languageIdOrSelection === 'string' ? languageIdOrSelection : languageIdOrSelection.languageId);
159
+ let creationOptions = this._modelCreationOptionsByLanguageAndResource[language + resource];
160
+ if (!creationOptions) {
161
+ const editor = this._configurationService.getValue('editor', { overrideIdentifier: language, resource });
162
+ const eol = this._getEOL(resource, language);
163
+ creationOptions = ModelService_1._readModelOptions({ editor, eol }, isForSimpleWidget);
164
+ this._modelCreationOptionsByLanguageAndResource[language + resource] = creationOptions;
165
+ }
166
+ return creationOptions;
167
+ }
168
+ _updateModelOptions(e) {
169
+ const oldOptionsByLanguageAndResource = this._modelCreationOptionsByLanguageAndResource;
170
+ this._modelCreationOptionsByLanguageAndResource = Object.create(null);
171
+ // Update options on all models
172
+ const keys = Object.keys(this._models);
173
+ for (let i = 0, len = keys.length; i < len; i++) {
174
+ const modelId = keys[i];
175
+ const modelData = this._models[modelId];
176
+ const language = modelData.model.getLanguageId();
177
+ const uri = modelData.model.uri;
178
+ if (e && !e.affectsConfiguration('editor', { overrideIdentifier: language, resource: uri }) && !e.affectsConfiguration('files.eol', { overrideIdentifier: language, resource: uri })) {
179
+ continue; // perf: skip if this model is not affected by configuration change
180
+ }
181
+ const oldOptions = oldOptionsByLanguageAndResource[language + uri];
182
+ const newOptions = this.getCreationOptions(language, uri, modelData.model.isForSimpleWidget);
183
+ ModelService_1._setModelOptionsForModel(modelData.model, newOptions, oldOptions);
184
+ }
185
+ }
186
+ static _setModelOptionsForModel(model, newOptions, currentOptions) {
187
+ if (currentOptions && currentOptions.defaultEOL !== newOptions.defaultEOL && model.getLineCount() === 1) {
188
+ model.setEOL(newOptions.defaultEOL === 1 /* DefaultEndOfLine.LF */ ? 0 /* EndOfLineSequence.LF */ : 1 /* EndOfLineSequence.CRLF */);
189
+ }
190
+ if (currentOptions
191
+ && (currentOptions.detectIndentation === newOptions.detectIndentation)
192
+ && (currentOptions.insertSpaces === newOptions.insertSpaces)
193
+ && (currentOptions.tabSize === newOptions.tabSize)
194
+ && (currentOptions.indentSize === newOptions.indentSize)
195
+ && (currentOptions.trimAutoWhitespace === newOptions.trimAutoWhitespace)
196
+ && equals(currentOptions.bracketPairColorizationOptions, newOptions.bracketPairColorizationOptions)) {
197
+ // Same indent opts, no need to touch the model
198
+ return;
199
+ }
200
+ if (newOptions.detectIndentation) {
201
+ model.detectIndentation(newOptions.insertSpaces, newOptions.tabSize);
202
+ model.updateOptions({
203
+ trimAutoWhitespace: newOptions.trimAutoWhitespace,
204
+ bracketColorizationOptions: newOptions.bracketPairColorizationOptions
205
+ });
206
+ }
207
+ else {
208
+ model.updateOptions({
209
+ insertSpaces: newOptions.insertSpaces,
210
+ tabSize: newOptions.tabSize,
211
+ indentSize: newOptions.indentSize,
212
+ trimAutoWhitespace: newOptions.trimAutoWhitespace,
213
+ bracketColorizationOptions: newOptions.bracketPairColorizationOptions
214
+ });
215
+ }
216
+ }
217
+ // --- begin IModelService
218
+ _insertDisposedModel(disposedModelData) {
219
+ this._disposedModels.set(MODEL_ID(disposedModelData.uri), disposedModelData);
220
+ this._disposedModelsHeapSize += disposedModelData.heapSize;
221
+ }
222
+ _removeDisposedModel(resource) {
223
+ const disposedModelData = this._disposedModels.get(MODEL_ID(resource));
224
+ if (disposedModelData) {
225
+ this._disposedModelsHeapSize -= disposedModelData.heapSize;
226
+ }
227
+ this._disposedModels.delete(MODEL_ID(resource));
228
+ return disposedModelData;
229
+ }
230
+ _ensureDisposedModelsHeapSize(maxModelsHeapSize) {
231
+ if (this._disposedModelsHeapSize > maxModelsHeapSize) {
232
+ // we must remove some old undo stack elements to free up some memory
233
+ const disposedModels = [];
234
+ this._disposedModels.forEach(entry => {
235
+ if (!entry.sharesUndoRedoStack) {
236
+ disposedModels.push(entry);
237
+ }
238
+ });
239
+ disposedModels.sort((a, b) => a.time - b.time);
240
+ while (disposedModels.length > 0 && this._disposedModelsHeapSize > maxModelsHeapSize) {
241
+ const disposedModel = disposedModels.shift();
242
+ this._removeDisposedModel(disposedModel.uri);
243
+ if (disposedModel.initialUndoRedoSnapshot !== null) {
244
+ this._undoRedoService.restoreSnapshot(disposedModel.initialUndoRedoSnapshot);
245
+ }
246
+ }
247
+ }
248
+ }
249
+ _createModelData(value, languageIdOrSelection, resource, isForSimpleWidget) {
250
+ // create & save the model
251
+ const options = this.getCreationOptions(languageIdOrSelection, resource, isForSimpleWidget);
252
+ const model = this._instantiationService.createInstance(TextModel, value, languageIdOrSelection, options, resource);
253
+ if (resource && this._disposedModels.has(MODEL_ID(resource))) {
254
+ const disposedModelData = this._removeDisposedModel(resource);
255
+ const elements = this._undoRedoService.getElements(resource);
256
+ const sha1Computer = this._getSHA1Computer();
257
+ const sha1IsEqual = (sha1Computer.canComputeSHA1(model)
258
+ ? sha1Computer.computeSHA1(model) === disposedModelData.sha1
259
+ : false);
260
+ if (sha1IsEqual || disposedModelData.sharesUndoRedoStack) {
261
+ for (const element of elements.past) {
262
+ if (isEditStackElement(element) && element.matchesResource(resource)) {
263
+ element.setModel(model);
264
+ }
265
+ }
266
+ for (const element of elements.future) {
267
+ if (isEditStackElement(element) && element.matchesResource(resource)) {
268
+ element.setModel(model);
269
+ }
270
+ }
271
+ this._undoRedoService.setElementsValidFlag(resource, true, (element) => (isEditStackElement(element) && element.matchesResource(resource)));
272
+ if (sha1IsEqual) {
273
+ model._overwriteVersionId(disposedModelData.versionId);
274
+ model._overwriteAlternativeVersionId(disposedModelData.alternativeVersionId);
275
+ model._overwriteInitialUndoRedoSnapshot(disposedModelData.initialUndoRedoSnapshot);
276
+ }
277
+ }
278
+ else {
279
+ if (disposedModelData.initialUndoRedoSnapshot !== null) {
280
+ this._undoRedoService.restoreSnapshot(disposedModelData.initialUndoRedoSnapshot);
281
+ }
282
+ }
283
+ }
284
+ const modelId = MODEL_ID(model.uri);
285
+ if (this._models[modelId]) {
286
+ // There already exists a model with this id => this is a programmer error
287
+ throw new Error('ModelService: Cannot add model because it already exists!');
288
+ }
289
+ const modelData = new ModelData(model, (model) => this._onWillDispose(model), (model, e) => this._onDidChangeLanguage(model, e));
290
+ this._models[modelId] = modelData;
291
+ return modelData;
292
+ }
293
+ createModel(value, languageSelection, resource, isForSimpleWidget = false) {
294
+ let modelData;
295
+ if (languageSelection) {
296
+ modelData = this._createModelData(value, languageSelection, resource, isForSimpleWidget);
297
+ }
298
+ else {
299
+ modelData = this._createModelData(value, PLAINTEXT_LANGUAGE_ID, resource, isForSimpleWidget);
300
+ }
301
+ this._onModelAdded.fire(modelData.model);
302
+ return modelData.model;
303
+ }
304
+ getModels() {
305
+ const ret = [];
306
+ const keys = Object.keys(this._models);
307
+ for (let i = 0, len = keys.length; i < len; i++) {
308
+ const modelId = keys[i];
309
+ ret.push(this._models[modelId].model);
310
+ }
311
+ return ret;
312
+ }
313
+ getModel(resource) {
314
+ const modelId = MODEL_ID(resource);
315
+ const modelData = this._models[modelId];
316
+ if (!modelData) {
317
+ return null;
318
+ }
319
+ return modelData.model;
320
+ }
321
+ // --- end IModelService
322
+ _schemaShouldMaintainUndoRedoElements(resource) {
323
+ return (resource.scheme === Schemas.file
324
+ || resource.scheme === Schemas.vscodeRemote
325
+ || resource.scheme === Schemas.vscodeUserData
326
+ || resource.scheme === Schemas.vscodeNotebookCell
327
+ || resource.scheme === 'fake-fs' // for tests
328
+ );
329
+ }
330
+ _onWillDispose(model) {
331
+ const modelId = MODEL_ID(model.uri);
332
+ const modelData = this._models[modelId];
333
+ const sharesUndoRedoStack = (this._undoRedoService.getUriComparisonKey(model.uri) !== model.uri.toString());
334
+ let maintainUndoRedoStack = false;
335
+ let heapSize = 0;
336
+ if (sharesUndoRedoStack || (this._shouldRestoreUndoStack() && this._schemaShouldMaintainUndoRedoElements(model.uri))) {
337
+ const elements = this._undoRedoService.getElements(model.uri);
338
+ if (elements.past.length > 0 || elements.future.length > 0) {
339
+ for (const element of elements.past) {
340
+ if (isEditStackElement(element) && element.matchesResource(model.uri)) {
341
+ maintainUndoRedoStack = true;
342
+ heapSize += element.heapSize(model.uri);
343
+ element.setModel(model.uri); // remove reference from text buffer instance
344
+ }
345
+ }
346
+ for (const element of elements.future) {
347
+ if (isEditStackElement(element) && element.matchesResource(model.uri)) {
348
+ maintainUndoRedoStack = true;
349
+ heapSize += element.heapSize(model.uri);
350
+ element.setModel(model.uri); // remove reference from text buffer instance
351
+ }
352
+ }
353
+ }
354
+ }
355
+ const maxMemory = ModelService_1.MAX_MEMORY_FOR_CLOSED_FILES_UNDO_STACK;
356
+ const sha1Computer = this._getSHA1Computer();
357
+ if (!maintainUndoRedoStack) {
358
+ if (!sharesUndoRedoStack) {
359
+ const initialUndoRedoSnapshot = modelData.model.getInitialUndoRedoSnapshot();
360
+ if (initialUndoRedoSnapshot !== null) {
361
+ this._undoRedoService.restoreSnapshot(initialUndoRedoSnapshot);
362
+ }
363
+ }
364
+ }
365
+ else if (!sharesUndoRedoStack && (heapSize > maxMemory || !sha1Computer.canComputeSHA1(model))) {
366
+ // the undo stack for this file would never fit in the configured memory or the file is very large, so don't bother with it.
367
+ const initialUndoRedoSnapshot = modelData.model.getInitialUndoRedoSnapshot();
368
+ if (initialUndoRedoSnapshot !== null) {
369
+ this._undoRedoService.restoreSnapshot(initialUndoRedoSnapshot);
370
+ }
371
+ }
372
+ else {
373
+ this._ensureDisposedModelsHeapSize(maxMemory - heapSize);
374
+ // We only invalidate the elements, but they remain in the undo-redo service.
375
+ this._undoRedoService.setElementsValidFlag(model.uri, false, (element) => (isEditStackElement(element) && element.matchesResource(model.uri)));
376
+ this._insertDisposedModel(new DisposedModelInfo(model.uri, modelData.model.getInitialUndoRedoSnapshot(), Date.now(), sharesUndoRedoStack, heapSize, sha1Computer.computeSHA1(model), model.getVersionId(), model.getAlternativeVersionId()));
377
+ }
378
+ delete this._models[modelId];
379
+ modelData.dispose();
380
+ // clean up cache
381
+ delete this._modelCreationOptionsByLanguageAndResource[model.getLanguageId() + model.uri];
382
+ this._onModelRemoved.fire(model);
383
+ }
384
+ _onDidChangeLanguage(model, e) {
385
+ const oldLanguageId = e.oldLanguage;
386
+ const newLanguageId = model.getLanguageId();
387
+ const oldOptions = this.getCreationOptions(oldLanguageId, model.uri, model.isForSimpleWidget);
388
+ const newOptions = this.getCreationOptions(newLanguageId, model.uri, model.isForSimpleWidget);
389
+ ModelService_1._setModelOptionsForModel(model, newOptions, oldOptions);
390
+ this._onModelModeChanged.fire({ model, oldLanguageId: oldLanguageId });
391
+ }
392
+ _getSHA1Computer() {
393
+ return new DefaultModelSHA1Computer();
394
+ }
395
+ };
396
+ ModelService = ModelService_1 = __decorate([
397
+ __param(0, IConfigurationService),
398
+ __param(1, ITextResourcePropertiesService),
399
+ __param(2, IUndoRedoService),
400
+ __param(3, IInstantiationService)
401
+ ], ModelService);
402
+ export { ModelService };
403
+ export class DefaultModelSHA1Computer {
404
+ static { this.MAX_MODEL_SIZE = 10 * 1024 * 1024; } // takes 200ms to compute a sha1 on a 10MB model on a new machine
405
+ canComputeSHA1(model) {
406
+ return (model.getValueLength() <= DefaultModelSHA1Computer.MAX_MODEL_SIZE);
407
+ }
408
+ computeSHA1(model) {
409
+ // compute the sha1
410
+ const shaComputer = new StringSHA1();
411
+ const snapshot = model.createSnapshot();
412
+ let text;
413
+ while ((text = snapshot.read())) {
414
+ shaComputer.update(text);
415
+ }
416
+ return shaComputer.digest();
417
+ }
418
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/resolverService.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
2
+ export const ITextModelService = createDecorator('textModelService');
node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensDto.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { VSBuffer } from '../../../base/common/buffer.js';
6
+ import * as platform from '../../../base/common/platform.js';
7
+ function reverseEndianness(arr) {
8
+ for (let i = 0, len = arr.length; i < len; i += 4) {
9
+ // flip bytes 0<->3 and 1<->2
10
+ const b0 = arr[i + 0];
11
+ const b1 = arr[i + 1];
12
+ const b2 = arr[i + 2];
13
+ const b3 = arr[i + 3];
14
+ arr[i + 0] = b3;
15
+ arr[i + 1] = b2;
16
+ arr[i + 2] = b1;
17
+ arr[i + 3] = b0;
18
+ }
19
+ }
20
+ function toLittleEndianBuffer(arr) {
21
+ const uint8Arr = new Uint8Array(arr.buffer, arr.byteOffset, arr.length * 4);
22
+ if (!platform.isLittleEndian()) {
23
+ // the byte order must be changed
24
+ reverseEndianness(uint8Arr);
25
+ }
26
+ return VSBuffer.wrap(uint8Arr);
27
+ }
28
+ export function encodeSemanticTokensDto(semanticTokens) {
29
+ const dest = new Uint32Array(encodeSemanticTokensDtoSize(semanticTokens));
30
+ let offset = 0;
31
+ dest[offset++] = semanticTokens.id;
32
+ if (semanticTokens.type === 'full') {
33
+ dest[offset++] = 1 /* EncodedSemanticTokensType.Full */;
34
+ dest[offset++] = semanticTokens.data.length;
35
+ dest.set(semanticTokens.data, offset);
36
+ offset += semanticTokens.data.length;
37
+ }
38
+ else {
39
+ dest[offset++] = 2 /* EncodedSemanticTokensType.Delta */;
40
+ dest[offset++] = semanticTokens.deltas.length;
41
+ for (const delta of semanticTokens.deltas) {
42
+ dest[offset++] = delta.start;
43
+ dest[offset++] = delta.deleteCount;
44
+ if (delta.data) {
45
+ dest[offset++] = delta.data.length;
46
+ dest.set(delta.data, offset);
47
+ offset += delta.data.length;
48
+ }
49
+ else {
50
+ dest[offset++] = 0;
51
+ }
52
+ }
53
+ }
54
+ return toLittleEndianBuffer(dest);
55
+ }
56
+ function encodeSemanticTokensDtoSize(semanticTokens) {
57
+ let result = 0;
58
+ result += (+1 // id
59
+ + 1 // type
60
+ );
61
+ if (semanticTokens.type === 'full') {
62
+ result += (+1 // data length
63
+ + semanticTokens.data.length);
64
+ }
65
+ else {
66
+ result += (+1 // delta count
67
+ );
68
+ result += (+1 // start
69
+ + 1 // deleteCount
70
+ + 1 // data length
71
+ ) * semanticTokens.deltas.length;
72
+ for (const delta of semanticTokens.deltas) {
73
+ if (delta.data) {
74
+ result += delta.data.length;
75
+ }
76
+ }
77
+ }
78
+ return result;
79
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensProviderStyling.js ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
6
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
8
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ import { TokenMetadata } from '../encodedTokenAttributes.js';
15
+ import { IThemeService } from '../../../platform/theme/common/themeService.js';
16
+ import { ILogService, LogLevel } from '../../../platform/log/common/log.js';
17
+ import { SparseMultilineTokens } from '../tokens/sparseMultilineTokens.js';
18
+ import { ILanguageService } from '../languages/language.js';
19
+ const ENABLE_TRACE = false;
20
+ let SemanticTokensProviderStyling = class SemanticTokensProviderStyling {
21
+ constructor(_legend, _themeService, _languageService, _logService) {
22
+ this._legend = _legend;
23
+ this._themeService = _themeService;
24
+ this._languageService = _languageService;
25
+ this._logService = _logService;
26
+ this._hasWarnedOverlappingTokens = false;
27
+ this._hasWarnedInvalidLengthTokens = false;
28
+ this._hasWarnedInvalidEditStart = false;
29
+ this._hashTable = new HashTable();
30
+ }
31
+ getMetadata(tokenTypeIndex, tokenModifierSet, languageId) {
32
+ const encodedLanguageId = this._languageService.languageIdCodec.encodeLanguageId(languageId);
33
+ const entry = this._hashTable.get(tokenTypeIndex, tokenModifierSet, encodedLanguageId);
34
+ let metadata;
35
+ if (entry) {
36
+ metadata = entry.metadata;
37
+ if (ENABLE_TRACE && this._logService.getLevel() === LogLevel.Trace) {
38
+ this._logService.trace(`SemanticTokensProviderStyling [CACHED] ${tokenTypeIndex} / ${tokenModifierSet}: foreground ${TokenMetadata.getForeground(metadata)}, fontStyle ${TokenMetadata.getFontStyle(metadata).toString(2)}`);
39
+ }
40
+ }
41
+ else {
42
+ let tokenType = this._legend.tokenTypes[tokenTypeIndex];
43
+ const tokenModifiers = [];
44
+ if (tokenType) {
45
+ let modifierSet = tokenModifierSet;
46
+ for (let modifierIndex = 0; modifierSet > 0 && modifierIndex < this._legend.tokenModifiers.length; modifierIndex++) {
47
+ if (modifierSet & 1) {
48
+ tokenModifiers.push(this._legend.tokenModifiers[modifierIndex]);
49
+ }
50
+ modifierSet = modifierSet >> 1;
51
+ }
52
+ if (ENABLE_TRACE && modifierSet > 0 && this._logService.getLevel() === LogLevel.Trace) {
53
+ this._logService.trace(`SemanticTokensProviderStyling: unknown token modifier index: ${tokenModifierSet.toString(2)} for legend: ${JSON.stringify(this._legend.tokenModifiers)}`);
54
+ tokenModifiers.push('not-in-legend');
55
+ }
56
+ const tokenStyle = this._themeService.getColorTheme().getTokenStyleMetadata(tokenType, tokenModifiers, languageId);
57
+ if (typeof tokenStyle === 'undefined') {
58
+ metadata = 2147483647 /* SemanticTokensProviderStylingConstants.NO_STYLING */;
59
+ }
60
+ else {
61
+ metadata = 0;
62
+ if (typeof tokenStyle.italic !== 'undefined') {
63
+ const italicBit = (tokenStyle.italic ? 1 /* FontStyle.Italic */ : 0) << 11 /* MetadataConsts.FONT_STYLE_OFFSET */;
64
+ metadata |= italicBit | 1 /* MetadataConsts.SEMANTIC_USE_ITALIC */;
65
+ }
66
+ if (typeof tokenStyle.bold !== 'undefined') {
67
+ const boldBit = (tokenStyle.bold ? 2 /* FontStyle.Bold */ : 0) << 11 /* MetadataConsts.FONT_STYLE_OFFSET */;
68
+ metadata |= boldBit | 2 /* MetadataConsts.SEMANTIC_USE_BOLD */;
69
+ }
70
+ if (typeof tokenStyle.underline !== 'undefined') {
71
+ const underlineBit = (tokenStyle.underline ? 4 /* FontStyle.Underline */ : 0) << 11 /* MetadataConsts.FONT_STYLE_OFFSET */;
72
+ metadata |= underlineBit | 4 /* MetadataConsts.SEMANTIC_USE_UNDERLINE */;
73
+ }
74
+ if (typeof tokenStyle.strikethrough !== 'undefined') {
75
+ const strikethroughBit = (tokenStyle.strikethrough ? 8 /* FontStyle.Strikethrough */ : 0) << 11 /* MetadataConsts.FONT_STYLE_OFFSET */;
76
+ metadata |= strikethroughBit | 8 /* MetadataConsts.SEMANTIC_USE_STRIKETHROUGH */;
77
+ }
78
+ if (tokenStyle.foreground) {
79
+ const foregroundBits = (tokenStyle.foreground) << 15 /* MetadataConsts.FOREGROUND_OFFSET */;
80
+ metadata |= foregroundBits | 16 /* MetadataConsts.SEMANTIC_USE_FOREGROUND */;
81
+ }
82
+ if (metadata === 0) {
83
+ // Nothing!
84
+ metadata = 2147483647 /* SemanticTokensProviderStylingConstants.NO_STYLING */;
85
+ }
86
+ }
87
+ }
88
+ else {
89
+ if (ENABLE_TRACE && this._logService.getLevel() === LogLevel.Trace) {
90
+ this._logService.trace(`SemanticTokensProviderStyling: unknown token type index: ${tokenTypeIndex} for legend: ${JSON.stringify(this._legend.tokenTypes)}`);
91
+ }
92
+ metadata = 2147483647 /* SemanticTokensProviderStylingConstants.NO_STYLING */;
93
+ tokenType = 'not-in-legend';
94
+ }
95
+ this._hashTable.add(tokenTypeIndex, tokenModifierSet, encodedLanguageId, metadata);
96
+ if (ENABLE_TRACE && this._logService.getLevel() === LogLevel.Trace) {
97
+ this._logService.trace(`SemanticTokensProviderStyling ${tokenTypeIndex} (${tokenType}) / ${tokenModifierSet} (${tokenModifiers.join(' ')}): foreground ${TokenMetadata.getForeground(metadata)}, fontStyle ${TokenMetadata.getFontStyle(metadata).toString(2)}`);
98
+ }
99
+ }
100
+ return metadata;
101
+ }
102
+ warnOverlappingSemanticTokens(lineNumber, startColumn) {
103
+ if (!this._hasWarnedOverlappingTokens) {
104
+ this._hasWarnedOverlappingTokens = true;
105
+ this._logService.warn(`Overlapping semantic tokens detected at lineNumber ${lineNumber}, column ${startColumn}`);
106
+ }
107
+ }
108
+ warnInvalidLengthSemanticTokens(lineNumber, startColumn) {
109
+ if (!this._hasWarnedInvalidLengthTokens) {
110
+ this._hasWarnedInvalidLengthTokens = true;
111
+ this._logService.warn(`Semantic token with invalid length detected at lineNumber ${lineNumber}, column ${startColumn}`);
112
+ }
113
+ }
114
+ warnInvalidEditStart(previousResultId, resultId, editIndex, editStart, maxExpectedStart) {
115
+ if (!this._hasWarnedInvalidEditStart) {
116
+ this._hasWarnedInvalidEditStart = true;
117
+ this._logService.warn(`Invalid semantic tokens edit detected (previousResultId: ${previousResultId}, resultId: ${resultId}) at edit #${editIndex}: The provided start offset ${editStart} is outside the previous data (length ${maxExpectedStart}).`);
118
+ }
119
+ }
120
+ };
121
+ SemanticTokensProviderStyling = __decorate([
122
+ __param(1, IThemeService),
123
+ __param(2, ILanguageService),
124
+ __param(3, ILogService)
125
+ ], SemanticTokensProviderStyling);
126
+ export { SemanticTokensProviderStyling };
127
+ export function toMultilineTokens2(tokens, styling, languageId) {
128
+ const srcData = tokens.data;
129
+ const tokenCount = (tokens.data.length / 5) | 0;
130
+ const tokensPerArea = Math.max(Math.ceil(tokenCount / 1024 /* SemanticColoringConstants.DesiredMaxAreas */), 400 /* SemanticColoringConstants.DesiredTokensPerArea */);
131
+ const result = [];
132
+ let tokenIndex = 0;
133
+ let lastLineNumber = 1;
134
+ let lastStartCharacter = 0;
135
+ while (tokenIndex < tokenCount) {
136
+ const tokenStartIndex = tokenIndex;
137
+ let tokenEndIndex = Math.min(tokenStartIndex + tokensPerArea, tokenCount);
138
+ // Keep tokens on the same line in the same area...
139
+ if (tokenEndIndex < tokenCount) {
140
+ let smallTokenEndIndex = tokenEndIndex;
141
+ while (smallTokenEndIndex - 1 > tokenStartIndex && srcData[5 * smallTokenEndIndex] === 0) {
142
+ smallTokenEndIndex--;
143
+ }
144
+ if (smallTokenEndIndex - 1 === tokenStartIndex) {
145
+ // there are so many tokens on this line that our area would be empty, we must now go right
146
+ let bigTokenEndIndex = tokenEndIndex;
147
+ while (bigTokenEndIndex + 1 < tokenCount && srcData[5 * bigTokenEndIndex] === 0) {
148
+ bigTokenEndIndex++;
149
+ }
150
+ tokenEndIndex = bigTokenEndIndex;
151
+ }
152
+ else {
153
+ tokenEndIndex = smallTokenEndIndex;
154
+ }
155
+ }
156
+ let destData = new Uint32Array((tokenEndIndex - tokenStartIndex) * 4);
157
+ let destOffset = 0;
158
+ let areaLine = 0;
159
+ let prevLineNumber = 0;
160
+ let prevEndCharacter = 0;
161
+ while (tokenIndex < tokenEndIndex) {
162
+ const srcOffset = 5 * tokenIndex;
163
+ const deltaLine = srcData[srcOffset];
164
+ const deltaCharacter = srcData[srcOffset + 1];
165
+ // Casting both `lineNumber`, `startCharacter` and `endCharacter` here to uint32 using `|0`
166
+ // to validate below with the actual values that will be inserted in the Uint32Array result
167
+ const lineNumber = (lastLineNumber + deltaLine) | 0;
168
+ const startCharacter = (deltaLine === 0 ? (lastStartCharacter + deltaCharacter) | 0 : deltaCharacter);
169
+ const length = srcData[srcOffset + 2];
170
+ const endCharacter = (startCharacter + length) | 0;
171
+ const tokenTypeIndex = srcData[srcOffset + 3];
172
+ const tokenModifierSet = srcData[srcOffset + 4];
173
+ if (endCharacter <= startCharacter) {
174
+ // this token is invalid (most likely a negative length casted to uint32)
175
+ styling.warnInvalidLengthSemanticTokens(lineNumber, startCharacter + 1);
176
+ }
177
+ else if (prevLineNumber === lineNumber && prevEndCharacter > startCharacter) {
178
+ // this token overlaps with the previous token
179
+ styling.warnOverlappingSemanticTokens(lineNumber, startCharacter + 1);
180
+ }
181
+ else {
182
+ const metadata = styling.getMetadata(tokenTypeIndex, tokenModifierSet, languageId);
183
+ if (metadata !== 2147483647 /* SemanticTokensProviderStylingConstants.NO_STYLING */) {
184
+ if (areaLine === 0) {
185
+ areaLine = lineNumber;
186
+ }
187
+ destData[destOffset] = lineNumber - areaLine;
188
+ destData[destOffset + 1] = startCharacter;
189
+ destData[destOffset + 2] = endCharacter;
190
+ destData[destOffset + 3] = metadata;
191
+ destOffset += 4;
192
+ prevLineNumber = lineNumber;
193
+ prevEndCharacter = endCharacter;
194
+ }
195
+ }
196
+ lastLineNumber = lineNumber;
197
+ lastStartCharacter = startCharacter;
198
+ tokenIndex++;
199
+ }
200
+ if (destOffset !== destData.length) {
201
+ destData = destData.subarray(0, destOffset);
202
+ }
203
+ const tokens = SparseMultilineTokens.create(areaLine, destData);
204
+ result.push(tokens);
205
+ }
206
+ return result;
207
+ }
208
+ class HashTableEntry {
209
+ constructor(tokenTypeIndex, tokenModifierSet, languageId, metadata) {
210
+ this.tokenTypeIndex = tokenTypeIndex;
211
+ this.tokenModifierSet = tokenModifierSet;
212
+ this.languageId = languageId;
213
+ this.metadata = metadata;
214
+ this.next = null;
215
+ }
216
+ }
217
+ class HashTable {
218
+ static { this._SIZES = [3, 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 2097143]; }
219
+ constructor() {
220
+ this._elementsCount = 0;
221
+ this._currentLengthIndex = 0;
222
+ this._currentLength = HashTable._SIZES[this._currentLengthIndex];
223
+ this._growCount = Math.round(this._currentLengthIndex + 1 < HashTable._SIZES.length ? 2 / 3 * this._currentLength : 0);
224
+ this._elements = [];
225
+ HashTable._nullOutEntries(this._elements, this._currentLength);
226
+ }
227
+ static _nullOutEntries(entries, length) {
228
+ for (let i = 0; i < length; i++) {
229
+ entries[i] = null;
230
+ }
231
+ }
232
+ _hash2(n1, n2) {
233
+ return (((n1 << 5) - n1) + n2) | 0; // n1 * 31 + n2, keep as int32
234
+ }
235
+ _hashFunc(tokenTypeIndex, tokenModifierSet, languageId) {
236
+ return this._hash2(this._hash2(tokenTypeIndex, tokenModifierSet), languageId) % this._currentLength;
237
+ }
238
+ get(tokenTypeIndex, tokenModifierSet, languageId) {
239
+ const hash = this._hashFunc(tokenTypeIndex, tokenModifierSet, languageId);
240
+ let p = this._elements[hash];
241
+ while (p) {
242
+ if (p.tokenTypeIndex === tokenTypeIndex && p.tokenModifierSet === tokenModifierSet && p.languageId === languageId) {
243
+ return p;
244
+ }
245
+ p = p.next;
246
+ }
247
+ return null;
248
+ }
249
+ add(tokenTypeIndex, tokenModifierSet, languageId, metadata) {
250
+ this._elementsCount++;
251
+ if (this._growCount !== 0 && this._elementsCount >= this._growCount) {
252
+ // expand!
253
+ const oldElements = this._elements;
254
+ this._currentLengthIndex++;
255
+ this._currentLength = HashTable._SIZES[this._currentLengthIndex];
256
+ this._growCount = Math.round(this._currentLengthIndex + 1 < HashTable._SIZES.length ? 2 / 3 * this._currentLength : 0);
257
+ this._elements = [];
258
+ HashTable._nullOutEntries(this._elements, this._currentLength);
259
+ for (const first of oldElements) {
260
+ let p = first;
261
+ while (p) {
262
+ const oldNext = p.next;
263
+ p.next = null;
264
+ this._add(p);
265
+ p = oldNext;
266
+ }
267
+ }
268
+ }
269
+ this._add(new HashTableEntry(tokenTypeIndex, tokenModifierSet, languageId, metadata));
270
+ }
271
+ _add(element) {
272
+ const hash = this._hashFunc(element.tokenTypeIndex, element.tokenModifierSet, element.languageId);
273
+ element.next = this._elements[hash];
274
+ this._elements[hash] = element;
275
+ }
276
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensStyling.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
6
+ export const ISemanticTokensStylingService = createDecorator('semanticTokensStylingService');
node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensStylingService.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
6
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
8
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ import { Disposable } from '../../../base/common/lifecycle.js';
15
+ import { ILanguageService } from '../languages/language.js';
16
+ import { IThemeService } from '../../../platform/theme/common/themeService.js';
17
+ import { ILogService } from '../../../platform/log/common/log.js';
18
+ import { SemanticTokensProviderStyling } from './semanticTokensProviderStyling.js';
19
+ import { ISemanticTokensStylingService } from './semanticTokensStyling.js';
20
+ import { registerSingleton } from '../../../platform/instantiation/common/extensions.js';
21
+ let SemanticTokensStylingService = class SemanticTokensStylingService extends Disposable {
22
+ constructor(_themeService, _logService, _languageService) {
23
+ super();
24
+ this._themeService = _themeService;
25
+ this._logService = _logService;
26
+ this._languageService = _languageService;
27
+ this._caches = new WeakMap();
28
+ this._register(this._themeService.onDidColorThemeChange(() => {
29
+ this._caches = new WeakMap();
30
+ }));
31
+ }
32
+ getStyling(provider) {
33
+ if (!this._caches.has(provider)) {
34
+ this._caches.set(provider, new SemanticTokensProviderStyling(provider.getLegend(), this._themeService, this._languageService, this._logService));
35
+ }
36
+ return this._caches.get(provider);
37
+ }
38
+ };
39
+ SemanticTokensStylingService = __decorate([
40
+ __param(0, IThemeService),
41
+ __param(1, ILogService),
42
+ __param(2, ILanguageService)
43
+ ], SemanticTokensStylingService);
44
+ export { SemanticTokensStylingService };
45
+ registerSingleton(ISemanticTokensStylingService, SemanticTokensStylingService, 1 /* InstantiationType.Delayed */);
node_modules/monaco-editor/esm/vs/editor/common/services/textModelSync/textModelSync.impl.js ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { IntervalTimer } from '../../../../base/common/async.js';
6
+ import { Disposable, DisposableStore, dispose, toDisposable } from '../../../../base/common/lifecycle.js';
7
+ import { URI } from '../../../../base/common/uri.js';
8
+ import { Position } from '../../core/position.js';
9
+ import { Range } from '../../core/range.js';
10
+ import { ensureValidWordDefinition, getWordAtText } from '../../core/wordHelper.js';
11
+ import { MirrorTextModel as BaseMirrorModel } from '../../model/mirrorTextModel.js';
12
+ /**
13
+ * Stop syncing a model to the worker if it was not needed for 1 min.
14
+ */
15
+ export const STOP_SYNC_MODEL_DELTA_TIME_MS = 60 * 1000;
16
+ export class WorkerTextModelSyncClient extends Disposable {
17
+ constructor(proxy, modelService, keepIdleModels = false) {
18
+ super();
19
+ this._syncedModels = Object.create(null);
20
+ this._syncedModelsLastUsedTime = Object.create(null);
21
+ this._proxy = proxy;
22
+ this._modelService = modelService;
23
+ if (!keepIdleModels) {
24
+ const timer = new IntervalTimer();
25
+ timer.cancelAndSet(() => this._checkStopModelSync(), Math.round(STOP_SYNC_MODEL_DELTA_TIME_MS / 2));
26
+ this._register(timer);
27
+ }
28
+ }
29
+ dispose() {
30
+ for (const modelUrl in this._syncedModels) {
31
+ dispose(this._syncedModels[modelUrl]);
32
+ }
33
+ this._syncedModels = Object.create(null);
34
+ this._syncedModelsLastUsedTime = Object.create(null);
35
+ super.dispose();
36
+ }
37
+ ensureSyncedResources(resources, forceLargeModels = false) {
38
+ for (const resource of resources) {
39
+ const resourceStr = resource.toString();
40
+ if (!this._syncedModels[resourceStr]) {
41
+ this._beginModelSync(resource, forceLargeModels);
42
+ }
43
+ if (this._syncedModels[resourceStr]) {
44
+ this._syncedModelsLastUsedTime[resourceStr] = (new Date()).getTime();
45
+ }
46
+ }
47
+ }
48
+ _checkStopModelSync() {
49
+ const currentTime = (new Date()).getTime();
50
+ const toRemove = [];
51
+ for (const modelUrl in this._syncedModelsLastUsedTime) {
52
+ const elapsedTime = currentTime - this._syncedModelsLastUsedTime[modelUrl];
53
+ if (elapsedTime > STOP_SYNC_MODEL_DELTA_TIME_MS) {
54
+ toRemove.push(modelUrl);
55
+ }
56
+ }
57
+ for (const e of toRemove) {
58
+ this._stopModelSync(e);
59
+ }
60
+ }
61
+ _beginModelSync(resource, forceLargeModels) {
62
+ const model = this._modelService.getModel(resource);
63
+ if (!model) {
64
+ return;
65
+ }
66
+ if (!forceLargeModels && model.isTooLargeForSyncing()) {
67
+ return;
68
+ }
69
+ const modelUrl = resource.toString();
70
+ this._proxy.$acceptNewModel({
71
+ url: model.uri.toString(),
72
+ lines: model.getLinesContent(),
73
+ EOL: model.getEOL(),
74
+ versionId: model.getVersionId()
75
+ });
76
+ const toDispose = new DisposableStore();
77
+ toDispose.add(model.onDidChangeContent((e) => {
78
+ this._proxy.$acceptModelChanged(modelUrl.toString(), e);
79
+ }));
80
+ toDispose.add(model.onWillDispose(() => {
81
+ this._stopModelSync(modelUrl);
82
+ }));
83
+ toDispose.add(toDisposable(() => {
84
+ this._proxy.$acceptRemovedModel(modelUrl);
85
+ }));
86
+ this._syncedModels[modelUrl] = toDispose;
87
+ }
88
+ _stopModelSync(modelUrl) {
89
+ const toDispose = this._syncedModels[modelUrl];
90
+ delete this._syncedModels[modelUrl];
91
+ delete this._syncedModelsLastUsedTime[modelUrl];
92
+ dispose(toDispose);
93
+ }
94
+ }
95
+ export class WorkerTextModelSyncServer {
96
+ constructor() {
97
+ this._models = Object.create(null);
98
+ }
99
+ getModel(uri) {
100
+ return this._models[uri];
101
+ }
102
+ getModels() {
103
+ const all = [];
104
+ Object.keys(this._models).forEach((key) => all.push(this._models[key]));
105
+ return all;
106
+ }
107
+ $acceptNewModel(data) {
108
+ this._models[data.url] = new MirrorModel(URI.parse(data.url), data.lines, data.EOL, data.versionId);
109
+ }
110
+ $acceptModelChanged(uri, e) {
111
+ if (!this._models[uri]) {
112
+ return;
113
+ }
114
+ const model = this._models[uri];
115
+ model.onEvents(e);
116
+ }
117
+ $acceptRemovedModel(uri) {
118
+ if (!this._models[uri]) {
119
+ return;
120
+ }
121
+ delete this._models[uri];
122
+ }
123
+ }
124
+ export class MirrorModel extends BaseMirrorModel {
125
+ get uri() {
126
+ return this._uri;
127
+ }
128
+ get eol() {
129
+ return this._eol;
130
+ }
131
+ getValue() {
132
+ return this.getText();
133
+ }
134
+ findMatches(regex) {
135
+ const matches = [];
136
+ for (let i = 0; i < this._lines.length; i++) {
137
+ const line = this._lines[i];
138
+ const offsetToAdd = this.offsetAt(new Position(i + 1, 1));
139
+ const iteratorOverMatches = line.matchAll(regex);
140
+ for (const match of iteratorOverMatches) {
141
+ if (match.index || match.index === 0) {
142
+ match.index = match.index + offsetToAdd;
143
+ }
144
+ matches.push(match);
145
+ }
146
+ }
147
+ return matches;
148
+ }
149
+ getLinesContent() {
150
+ return this._lines.slice(0);
151
+ }
152
+ getLineCount() {
153
+ return this._lines.length;
154
+ }
155
+ getLineContent(lineNumber) {
156
+ return this._lines[lineNumber - 1];
157
+ }
158
+ getWordAtPosition(position, wordDefinition) {
159
+ const wordAtText = getWordAtText(position.column, ensureValidWordDefinition(wordDefinition), this._lines[position.lineNumber - 1], 0);
160
+ if (wordAtText) {
161
+ return new Range(position.lineNumber, wordAtText.startColumn, position.lineNumber, wordAtText.endColumn);
162
+ }
163
+ return null;
164
+ }
165
+ words(wordDefinition) {
166
+ const lines = this._lines;
167
+ const wordenize = this._wordenize.bind(this);
168
+ let lineNumber = 0;
169
+ let lineText = '';
170
+ let wordRangesIdx = 0;
171
+ let wordRanges = [];
172
+ return {
173
+ *[Symbol.iterator]() {
174
+ while (true) {
175
+ if (wordRangesIdx < wordRanges.length) {
176
+ const value = lineText.substring(wordRanges[wordRangesIdx].start, wordRanges[wordRangesIdx].end);
177
+ wordRangesIdx += 1;
178
+ yield value;
179
+ }
180
+ else {
181
+ if (lineNumber < lines.length) {
182
+ lineText = lines[lineNumber];
183
+ wordRanges = wordenize(lineText, wordDefinition);
184
+ wordRangesIdx = 0;
185
+ lineNumber += 1;
186
+ }
187
+ else {
188
+ break;
189
+ }
190
+ }
191
+ }
192
+ }
193
+ };
194
+ }
195
+ getLineWords(lineNumber, wordDefinition) {
196
+ const content = this._lines[lineNumber - 1];
197
+ const ranges = this._wordenize(content, wordDefinition);
198
+ const words = [];
199
+ for (const range of ranges) {
200
+ words.push({
201
+ word: content.substring(range.start, range.end),
202
+ startColumn: range.start + 1,
203
+ endColumn: range.end + 1
204
+ });
205
+ }
206
+ return words;
207
+ }
208
+ _wordenize(content, wordDefinition) {
209
+ const result = [];
210
+ let match;
211
+ wordDefinition.lastIndex = 0; // reset lastIndex just to be sure
212
+ while (match = wordDefinition.exec(content)) {
213
+ if (match[0].length === 0) {
214
+ // it did match the empty string
215
+ break;
216
+ }
217
+ result.push({ start: match.index, end: match.index + match[0].length });
218
+ }
219
+ return result;
220
+ }
221
+ getValueInRange(range) {
222
+ range = this._validateRange(range);
223
+ if (range.startLineNumber === range.endLineNumber) {
224
+ return this._lines[range.startLineNumber - 1].substring(range.startColumn - 1, range.endColumn - 1);
225
+ }
226
+ const lineEnding = this._eol;
227
+ const startLineIndex = range.startLineNumber - 1;
228
+ const endLineIndex = range.endLineNumber - 1;
229
+ const resultLines = [];
230
+ resultLines.push(this._lines[startLineIndex].substring(range.startColumn - 1));
231
+ for (let i = startLineIndex + 1; i < endLineIndex; i++) {
232
+ resultLines.push(this._lines[i]);
233
+ }
234
+ resultLines.push(this._lines[endLineIndex].substring(0, range.endColumn - 1));
235
+ return resultLines.join(lineEnding);
236
+ }
237
+ offsetAt(position) {
238
+ position = this._validatePosition(position);
239
+ this._ensureLineStarts();
240
+ return this._lineStarts.getPrefixSum(position.lineNumber - 2) + (position.column - 1);
241
+ }
242
+ positionAt(offset) {
243
+ offset = Math.floor(offset);
244
+ offset = Math.max(0, offset);
245
+ this._ensureLineStarts();
246
+ const out = this._lineStarts.getIndexOf(offset);
247
+ const lineLength = this._lines[out.index].length;
248
+ // Ensure we return a valid position
249
+ return {
250
+ lineNumber: 1 + out.index,
251
+ column: 1 + Math.min(out.remainder, lineLength)
252
+ };
253
+ }
254
+ _validateRange(range) {
255
+ const start = this._validatePosition({ lineNumber: range.startLineNumber, column: range.startColumn });
256
+ const end = this._validatePosition({ lineNumber: range.endLineNumber, column: range.endColumn });
257
+ if (start.lineNumber !== range.startLineNumber
258
+ || start.column !== range.startColumn
259
+ || end.lineNumber !== range.endLineNumber
260
+ || end.column !== range.endColumn) {
261
+ return {
262
+ startLineNumber: start.lineNumber,
263
+ startColumn: start.column,
264
+ endLineNumber: end.lineNumber,
265
+ endColumn: end.column
266
+ };
267
+ }
268
+ return range;
269
+ }
270
+ _validatePosition(position) {
271
+ if (!Position.isIPosition(position)) {
272
+ throw new Error('bad position');
273
+ }
274
+ let { lineNumber, column } = position;
275
+ let hasChanged = false;
276
+ if (lineNumber < 1) {
277
+ lineNumber = 1;
278
+ column = 1;
279
+ hasChanged = true;
280
+ }
281
+ else if (lineNumber > this._lines.length) {
282
+ lineNumber = this._lines.length;
283
+ column = this._lines[lineNumber - 1].length + 1;
284
+ hasChanged = true;
285
+ }
286
+ else {
287
+ const maxCharacter = this._lines[lineNumber - 1].length + 1;
288
+ if (column < 1) {
289
+ column = 1;
290
+ hasChanged = true;
291
+ }
292
+ else if (column > maxCharacter) {
293
+ column = maxCharacter;
294
+ hasChanged = true;
295
+ }
296
+ }
297
+ if (!hasChanged) {
298
+ return position;
299
+ }
300
+ else {
301
+ return { lineNumber, column };
302
+ }
303
+ }
304
+ }
node_modules/monaco-editor/esm/vs/editor/common/services/textModelSync/textModelSync.protocol.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export {};
node_modules/monaco-editor/esm/vs/editor/common/services/textResourceConfiguration.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
2
+ export const ITextResourceConfigurationService = createDecorator('textResourceConfigurationService');
3
+ export const ITextResourcePropertiesService = createDecorator('textResourcePropertiesService');
node_modules/monaco-editor/esm/vs/editor/common/services/treeSitterParserService.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
2
+ export const ITreeSitterParserService = createDecorator('treeSitterParserService');
node_modules/monaco-editor/esm/vs/editor/common/services/treeViewsDnd.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export class TreeViewsDnDService {
6
+ constructor() {
7
+ this._dragOperations = new Map();
8
+ }
9
+ removeDragOperationTransfer(uuid) {
10
+ if ((uuid && this._dragOperations.has(uuid))) {
11
+ const operation = this._dragOperations.get(uuid);
12
+ this._dragOperations.delete(uuid);
13
+ return operation;
14
+ }
15
+ return undefined;
16
+ }
17
+ }
18
+ export class DraggedTreeItemsIdentifier {
19
+ constructor(identifier) {
20
+ this.identifier = identifier;
21
+ }
22
+ }