monaco-editor11 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/css.worker-C7FogG4G.js +93 -0
- package/dist/assets/editor.worker-iXcRX1Tq.js +26 -0
- package/dist/assets/html.worker-C8VxctEJ.js +470 -0
- package/dist/assets/json.worker-CMC9kgPL.js +58 -0
- package/dist/assets/ts.worker-CtTJ3hNN.js +67731 -0
- package/dist/index.d.ts +0 -6
- package/dist/monaco-editor11.es.js +49 -78
- package/dist/monaco-editor11.umd.js +1 -50
- package/dist/monaco.d.ts +8 -0
- package/dist/workers/common/initialize.js +16 -0
- package/dist/workers/common/workers.js +141 -0
- package/dist/workers/editor/common/abstractSyntaxTokenBackend.js +128 -0
- package/dist/workers/editor/common/abstractText.js +89 -0
- package/dist/workers/editor/common/ast.js +485 -0
- package/dist/workers/editor/common/autoIndent.js +390 -0
- package/dist/workers/editor/common/beforeEditPositionMapper.js +110 -0
- package/dist/workers/editor/common/bracketPairsImpl.js +717 -0
- package/dist/workers/editor/common/bracketPairsTree.js +343 -0
- package/dist/workers/editor/common/brackets.js +108 -0
- package/dist/workers/editor/common/characterClassifier.js +59 -0
- package/dist/workers/editor/common/characterPair.js +40 -0
- package/dist/workers/editor/common/colorizedBracketPairsDecorationProvider.js +97 -0
- package/dist/workers/editor/common/columnRange.js +35 -0
- package/dist/workers/editor/common/combineTextEditInfos.js +124 -0
- package/dist/workers/editor/common/common.js +20 -0
- package/dist/workers/editor/common/computeMovedLines.js +249 -0
- package/dist/workers/editor/common/concat23Trees.js +192 -0
- package/dist/workers/editor/common/contiguousMultilineTokens.js +32 -0
- package/dist/workers/editor/common/contiguousMultilineTokensBuilder.js +23 -0
- package/dist/workers/editor/common/contiguousTokensEditing.js +128 -0
- package/dist/workers/editor/common/contiguousTokensStore.js +207 -0
- package/dist/workers/editor/common/coordinatesConverter.js +51 -0
- package/dist/workers/editor/common/cursor.js +899 -0
- package/dist/workers/editor/common/cursorAtomicMoveOperations.js +145 -0
- package/dist/workers/editor/common/cursorCollection.js +194 -0
- package/dist/workers/editor/common/cursorColumnSelection.js +93 -0
- package/dist/workers/editor/common/cursorColumns.js +112 -0
- package/dist/workers/editor/common/cursorCommon.js +250 -0
- package/dist/workers/editor/common/cursorContext.js +15 -0
- package/dist/workers/editor/common/cursorDeleteOperations.js +231 -0
- package/dist/workers/editor/common/cursorMoveCommands.js +676 -0
- package/dist/workers/editor/common/cursorMoveOperations.js +290 -0
- package/dist/workers/editor/common/cursorTypeEditOperations.js +968 -0
- package/dist/workers/editor/common/cursorTypeOperations.js +173 -0
- package/dist/workers/editor/common/cursorUtils.js +75 -0
- package/dist/workers/editor/common/cursorWordOperations.js +720 -0
- package/dist/workers/editor/common/defaultDocumentColorsComputer.js +138 -0
- package/dist/workers/editor/common/defaultLinesDiffComputer.js +188 -0
- package/dist/workers/editor/common/diffAlgorithm.js +139 -0
- package/dist/workers/editor/common/diffEditor.js +38 -0
- package/dist/workers/editor/common/dynamicProgrammingDiffing.js +101 -0
- package/dist/workers/editor/common/edit.js +183 -0
- package/dist/workers/editor/common/editOperation.js +36 -0
- package/dist/workers/editor/common/editStack.js +363 -0
- package/dist/workers/editor/common/editorAction.js +26 -0
- package/dist/workers/editor/common/editorBaseApi.js +43 -0
- package/dist/workers/editor/common/editorColorRegistry.js +102 -0
- package/dist/workers/editor/common/editorCommon.js +13 -0
- package/dist/workers/editor/common/editorConfigurationSchema.js +338 -0
- package/dist/workers/editor/common/editorContextKeys.js +84 -0
- package/dist/workers/editor/common/editorFeatures.js +17 -0
- package/dist/workers/editor/common/editorOptions.js +3440 -0
- package/dist/workers/editor/common/editorTheme.js +23 -0
- package/dist/workers/editor/common/editorWebWorker.js +299 -0
- package/dist/workers/editor/common/editorWorker.js +9 -0
- package/dist/workers/editor/common/editorWorkerHost.js +15 -0
- package/dist/workers/editor/common/editorZoom.js +26 -0
- package/dist/workers/editor/common/electricCharacter.js +55 -0
- package/dist/workers/editor/common/encodedTokenAttributes.js +79 -0
- package/dist/workers/editor/common/enterAction.js +53 -0
- package/dist/workers/editor/common/eolCounter.js +44 -0
- package/dist/workers/editor/common/findSectionHeaders.js +128 -0
- package/dist/workers/editor/common/fixBrackets.js +67 -0
- package/dist/workers/editor/common/fixedArray.js +70 -0
- package/dist/workers/editor/common/fontInfo.js +172 -0
- package/dist/workers/editor/common/fontInfoFromSettings.js +29 -0
- package/dist/workers/editor/common/getIconClasses.js +106 -0
- package/dist/workers/editor/common/getPositionOffsetTransformerFromTextModel.js +24 -0
- package/dist/workers/editor/common/glyphLanesModel.js +61 -0
- package/dist/workers/editor/common/guidesTextModelPart.js +405 -0
- package/dist/workers/editor/common/heuristicSequenceOptimizations.js +374 -0
- package/dist/workers/editor/common/indentRules.js +63 -0
- package/dist/workers/editor/common/indentation.js +39 -0
- package/dist/workers/editor/common/indentationGuesser.js +178 -0
- package/dist/workers/editor/common/indentationLineProcessor.js +193 -0
- package/dist/workers/editor/common/inlineDecorations.js +26 -0
- package/dist/workers/editor/common/inplaceReplaceSupport.js +87 -0
- package/dist/workers/editor/common/inputMode.js +22 -0
- package/dist/workers/editor/common/intervalTree.js +1002 -0
- package/dist/workers/editor/common/language.js +9 -0
- package/dist/workers/editor/common/languageBracketsConfiguration.js +133 -0
- package/dist/workers/editor/common/languageConfiguration.js +138 -0
- package/dist/workers/editor/common/languageConfigurationRegistry.js +361 -0
- package/dist/workers/editor/common/languageFeatureDebounce.js +137 -0
- package/dist/workers/editor/common/languageFeatureRegistry.js +180 -0
- package/dist/workers/editor/common/languageFeatures.js +9 -0
- package/dist/workers/editor/common/languageFeaturesService.js +47 -0
- package/dist/workers/editor/common/languageSelector.js +112 -0
- package/dist/workers/editor/common/languageService.js +92 -0
- package/dist/workers/editor/common/languages.js +522 -0
- package/dist/workers/editor/common/languagesAssociations.js +193 -0
- package/dist/workers/editor/common/languagesRegistry.js +237 -0
- package/dist/workers/editor/common/legacyLinesDiffComputer.js +468 -0
- package/dist/workers/editor/common/length.js +129 -0
- package/dist/workers/editor/common/lineDecorations.js +208 -0
- package/dist/workers/editor/common/lineEdit.js +75 -0
- package/dist/workers/editor/common/lineHeights.js +370 -0
- package/dist/workers/editor/common/linePart.js +25 -0
- package/dist/workers/editor/common/lineRange.js +312 -0
- package/dist/workers/editor/common/lineSequence.js +36 -0
- package/dist/workers/editor/common/lineTokens.js +405 -0
- package/dist/workers/editor/common/linesDiffComputer.js +29 -0
- package/dist/workers/editor/common/linesDiffComputers.js +13 -0
- package/dist/workers/editor/common/linesLayout.js +765 -0
- package/dist/workers/editor/common/linesSliceCharSequence.js +205 -0
- package/dist/workers/editor/common/linkComputer.js +269 -0
- package/dist/workers/editor/common/markerDecorations.js +9 -0
- package/dist/workers/editor/common/markerDecorationsService.js +248 -0
- package/dist/workers/editor/common/minimapTokensColorTracker.js +58 -0
- package/dist/workers/editor/common/mirrorTextModel.js +117 -0
- package/dist/workers/editor/common/model.js +9 -0
- package/dist/workers/editor/common/modelLineProjection.js +350 -0
- package/dist/workers/editor/common/modelLineProjectionData.js +297 -0
- package/dist/workers/editor/common/modelService.js +413 -0
- package/dist/workers/editor/common/modesRegistry.js +75 -0
- package/dist/workers/editor/common/monospaceLineBreaksComputer.js +473 -0
- package/dist/workers/editor/common/myersDiffAlgorithm.js +159 -0
- package/dist/workers/editor/common/nodeReader.js +127 -0
- package/dist/workers/editor/common/nullTokenize.js +29 -0
- package/dist/workers/editor/common/offsetRange.js +225 -0
- package/dist/workers/editor/common/onEnter.js +109 -0
- package/dist/workers/editor/common/oneCursor.js +117 -0
- package/dist/workers/editor/common/overviewZoneManager.js +176 -0
- package/dist/workers/editor/common/parser.js +121 -0
- package/dist/workers/editor/common/pieceTreeBase.js +1473 -0
- package/dist/workers/editor/common/pieceTreeTextBuffer.js +461 -0
- package/dist/workers/editor/common/pieceTreeTextBufferBuilder.js +140 -0
- package/dist/workers/editor/common/point.js +50 -0
- package/dist/workers/editor/common/position.js +142 -0
- package/dist/workers/editor/common/positionToOffset.js +17 -0
- package/dist/workers/editor/common/positionToOffsetImpl.js +98 -0
- package/dist/workers/editor/common/prefixSumComputer.js +226 -0
- package/dist/workers/editor/common/range.js +421 -0
- package/dist/workers/editor/common/rangeMapping.js +229 -0
- package/dist/workers/editor/common/rangeSingleLine.js +17 -0
- package/dist/workers/editor/common/rbTreeBase.js +362 -0
- package/dist/workers/editor/common/rect.js +163 -0
- package/dist/workers/editor/common/replaceCommand.js +158 -0
- package/dist/workers/editor/common/resolverService.js +5 -0
- package/dist/workers/editor/common/rgba.js +35 -0
- package/dist/workers/editor/common/richEditBrackets.js +356 -0
- package/dist/workers/editor/common/selection.js +145 -0
- package/dist/workers/editor/common/semanticTokensDto.js +82 -0
- package/dist/workers/editor/common/semanticTokensProviderStyling.js +263 -0
- package/dist/workers/editor/common/semanticTokensStyling.js +9 -0
- package/dist/workers/editor/common/semanticTokensStylingService.js +47 -0
- package/dist/workers/editor/common/shiftCommand.js +241 -0
- package/dist/workers/editor/common/smallImmutableSet.js +108 -0
- package/dist/workers/editor/common/sparseMultilineTokens.js +548 -0
- package/dist/workers/editor/common/sparseTokensStore.js +210 -0
- package/dist/workers/editor/common/standaloneEnums.js +1017 -0
- package/dist/workers/editor/common/standaloneStrings.js +42 -0
- package/dist/workers/editor/common/stringBuilder.js +122 -0
- package/dist/workers/editor/common/stringEdit.js +165 -0
- package/dist/workers/editor/common/supports.js +58 -0
- package/dist/workers/editor/common/surroundSelectionCommand.js +44 -0
- package/dist/workers/editor/common/textChange.js +248 -0
- package/dist/workers/editor/common/textEdit.js +269 -0
- package/dist/workers/editor/common/textLength.js +87 -0
- package/dist/workers/editor/common/textModel.js +2031 -0
- package/dist/workers/editor/common/textModelBracketPairs.js +45 -0
- package/dist/workers/editor/common/textModelDefaults.js +18 -0
- package/dist/workers/editor/common/textModelEditSource.js +166 -0
- package/dist/workers/editor/common/textModelEvents.js +216 -0
- package/dist/workers/editor/common/textModelGuides.js +40 -0
- package/dist/workers/editor/common/textModelPart.js +23 -0
- package/dist/workers/editor/common/textModelSearch.js +455 -0
- package/dist/workers/editor/common/textModelStringEdit.js +11 -0
- package/dist/workers/editor/common/textModelSync.impl.js +307 -0
- package/dist/workers/editor/common/textModelText.js +26 -0
- package/dist/workers/editor/common/textModelTokens.js +436 -0
- package/dist/workers/editor/common/textResourceConfiguration.js +6 -0
- package/dist/workers/editor/common/textToHtmlTokenizer.js +139 -0
- package/dist/workers/editor/common/tokenStore.js +407 -0
- package/dist/workers/editor/common/tokenWithTextArray.js +73 -0
- package/dist/workers/editor/common/tokenization.js +287 -0
- package/dist/workers/editor/common/tokenizationRegistry.js +123 -0
- package/dist/workers/editor/common/tokenizationTextModelPart.js +275 -0
- package/dist/workers/editor/common/tokenizer.js +301 -0
- package/dist/workers/editor/common/tokenizerSyntaxTokenBackend.js +261 -0
- package/dist/workers/editor/common/treeSitterLibraryService.js +9 -0
- package/dist/workers/editor/common/treeSitterSyntaxTokenBackend.js +167 -0
- package/dist/workers/editor/common/treeSitterThemeService.js +9 -0
- package/dist/workers/editor/common/treeSitterTokenizationImpl.js +713 -0
- package/dist/workers/editor/common/treeSitterTree.js +395 -0
- package/dist/workers/editor/common/treeViewsDnd.js +24 -0
- package/dist/workers/editor/common/treeViewsDndService.js +12 -0
- package/dist/workers/editor/common/trimTrailingWhitespaceCommand.js +98 -0
- package/dist/workers/editor/common/unicodeTextModelHighlighter.js +188 -0
- package/dist/workers/editor/common/utils.js +62 -0
- package/dist/workers/editor/common/viewContext.js +22 -0
- package/dist/workers/editor/common/viewEventHandler.js +186 -0
- package/dist/workers/editor/common/viewEvents.js +180 -0
- package/dist/workers/editor/common/viewLayout.js +368 -0
- package/dist/workers/editor/common/viewLineRenderer.js +948 -0
- package/dist/workers/editor/common/viewLinesViewportData.js +30 -0
- package/dist/workers/editor/common/viewModel.js +98 -0
- package/dist/workers/editor/common/viewModelDecoration.js +55 -0
- package/dist/workers/editor/common/viewModelDecorations.js +132 -0
- package/dist/workers/editor/common/viewModelEventDispatcher.js +398 -0
- package/dist/workers/editor/common/viewModelImpl.js +1163 -0
- package/dist/workers/editor/common/viewModelLines.js +938 -0
- package/dist/workers/editor/common/wordCharacterClassifier.js +87 -0
- package/dist/workers/editor/common/wordHelper.js +127 -0
- package/dist/workers/editor/editor.worker.js +11 -0
- package/dist/workers/language/css.worker.js +8 -0
- package/dist/workers/language/cssMode.js +198 -0
- package/dist/workers/language/cssWorker.js +183 -0
- package/dist/workers/language/html.worker.js +8 -0
- package/dist/workers/language/htmlMode.js +213 -0
- package/dist/workers/language/htmlWorker.js +126 -0
- package/dist/workers/language/json.worker.js +8 -0
- package/dist/workers/language/jsonMode.js +224 -0
- package/dist/workers/language/jsonWorker.js +187 -0
- package/dist/workers/language/languageFeatures.js +1009 -0
- package/dist/workers/language/lib.index.js +103 -0
- package/dist/workers/language/lib.js +1107 -0
- package/dist/workers/language/lspLanguageFeatures.js +716 -0
- package/dist/workers/language/monaco.contribution.js +144 -0
- package/dist/workers/language/tokenization.js +189 -0
- package/dist/workers/language/ts.worker.js +14 -0
- package/dist/workers/language/tsMode.js +212 -0
- package/dist/workers/language/tsWorker.js +352 -0
- package/dist/workers/language/typescriptServices.js +210154 -0
- package/dist/workers/language/typescriptServicesMetadata.js +3 -0
- package/dist/workers/language/workerManager.js +65 -0
- package/package.json +3 -2
|
@@ -0,0 +1,2031 @@
|
|
|
1
|
+
import { ArrayQueue, pushMany } from '../../../base/common/arrays.js';
|
|
2
|
+
import { Color } from '../../../base/common/color.js';
|
|
3
|
+
import { BugIndicatingError, illegalArgument, onUnexpectedError } from '../../../base/common/errors.js';
|
|
4
|
+
import { Emitter } from '../../../base/common/event.js';
|
|
5
|
+
import { Disposable, combinedDisposable, MutableDisposable } from '../../../base/common/lifecycle.js';
|
|
6
|
+
import { singleLetterHash, UNUSUAL_LINE_TERMINATORS, isHighSurrogate, htmlAttributeEncodeValue } from '../../../base/common/strings.js';
|
|
7
|
+
import { URI } from '../../../base/common/uri.js';
|
|
8
|
+
import { countEOL } from '../core/misc/eolCounter.js';
|
|
9
|
+
import { normalizeIndentation } from '../core/misc/indentation.js';
|
|
10
|
+
import { Position } from '../core/position.js';
|
|
11
|
+
import { Range } from '../core/range.js';
|
|
12
|
+
import { Selection } from '../core/selection.js';
|
|
13
|
+
import { EDITOR_MODEL_DEFAULTS } from '../core/misc/textModelDefaults.js';
|
|
14
|
+
import { ILanguageService } from '../languages/language.js';
|
|
15
|
+
import { ILanguageConfigurationService } from '../languages/languageConfigurationRegistry.js';
|
|
16
|
+
import { TextModelResolvedOptions, ValidAnnotatedEditOperation, isITextSnapshot, OverviewRulerLane, GlyphMarginLane } from '../model.js';
|
|
17
|
+
import { BracketPairsTextModelPart } from './bracketPairsTextModelPart/bracketPairsImpl.js';
|
|
18
|
+
import { ColorizedBracketPairsDecorationProvider } from './bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.js';
|
|
19
|
+
import { EditStack } from './editStack.js';
|
|
20
|
+
import { GuidesTextModelPart } from './guidesTextModelPart.js';
|
|
21
|
+
import { guessIndentation } from './indentationGuesser.js';
|
|
22
|
+
import { recomputeMaxEnd, IntervalNode, IntervalTree } from './intervalTree.js';
|
|
23
|
+
import { PieceTreeTextBuffer } from './pieceTreeTextBuffer/pieceTreeTextBuffer.js';
|
|
24
|
+
import { PieceTreeTextBufferBuilder } from './pieceTreeTextBuffer/pieceTreeTextBufferBuilder.js';
|
|
25
|
+
import { SearchParams, TextModelSearch } from './textModelSearch.js';
|
|
26
|
+
import { TokenizationTextModelPart } from './tokens/tokenizationTextModelPart.js';
|
|
27
|
+
import { AttachedViews } from './tokens/abstractSyntaxTokenBackend.js';
|
|
28
|
+
import { InternalModelContentChangeEvent, ModelRawContentChangedEvent, ModelRawFlush, ModelRawEOLChanged, LineInjectedText, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted, ModelInjectedTextChangedEvent, ModelLineHeightChanged, ModelLineHeightChangedEvent, ModelFontChanged, ModelFontChangedEvent } from '../textModelEvents.js';
|
|
29
|
+
import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js';
|
|
30
|
+
import { IUndoRedoService } from '../../../platform/undoRedo/common/undoRedo.js';
|
|
31
|
+
import { SetWithKey } from '../../../base/common/collections.js';
|
|
32
|
+
import { EditSources } from '../textModelEditSource.js';
|
|
33
|
+
import { isDark } from '../../../platform/theme/common/theme.js';
|
|
34
|
+
|
|
35
|
+
/*---------------------------------------------------------------------------------------------
|
|
36
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
37
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
38
|
+
*--------------------------------------------------------------------------------------------*/
|
|
39
|
+
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
40
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
41
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
42
|
+
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;
|
|
43
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
44
|
+
};
|
|
45
|
+
var __param = (undefined && undefined.__param) || function (paramIndex, decorator) {
|
|
46
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
47
|
+
};
|
|
48
|
+
var TextModel_1;
|
|
49
|
+
function createTextBufferFactory(text) {
|
|
50
|
+
const builder = new PieceTreeTextBufferBuilder();
|
|
51
|
+
builder.acceptChunk(text);
|
|
52
|
+
return builder.finish();
|
|
53
|
+
}
|
|
54
|
+
function createTextBufferFactoryFromSnapshot(snapshot) {
|
|
55
|
+
const builder = new PieceTreeTextBufferBuilder();
|
|
56
|
+
let chunk;
|
|
57
|
+
while (typeof (chunk = snapshot.read()) === 'string') {
|
|
58
|
+
builder.acceptChunk(chunk);
|
|
59
|
+
}
|
|
60
|
+
return builder.finish();
|
|
61
|
+
}
|
|
62
|
+
function createTextBuffer(value, defaultEOL) {
|
|
63
|
+
let factory;
|
|
64
|
+
if (typeof value === 'string') {
|
|
65
|
+
factory = createTextBufferFactory(value);
|
|
66
|
+
}
|
|
67
|
+
else if (isITextSnapshot(value)) {
|
|
68
|
+
factory = createTextBufferFactoryFromSnapshot(value);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
factory = value;
|
|
72
|
+
}
|
|
73
|
+
return factory.create(defaultEOL);
|
|
74
|
+
}
|
|
75
|
+
let MODEL_ID = 0;
|
|
76
|
+
const LIMIT_FIND_COUNT = 999;
|
|
77
|
+
const LONG_LINE_BOUNDARY = 10000;
|
|
78
|
+
const LINE_HEIGHT_CEILING = 300;
|
|
79
|
+
class TextModelSnapshot {
|
|
80
|
+
constructor(source) {
|
|
81
|
+
this._source = source;
|
|
82
|
+
this._eos = false;
|
|
83
|
+
}
|
|
84
|
+
read() {
|
|
85
|
+
if (this._eos) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
const result = [];
|
|
89
|
+
let resultCnt = 0;
|
|
90
|
+
let resultLength = 0;
|
|
91
|
+
do {
|
|
92
|
+
const tmp = this._source.read();
|
|
93
|
+
if (tmp === null) {
|
|
94
|
+
// end-of-stream
|
|
95
|
+
this._eos = true;
|
|
96
|
+
if (resultCnt === 0) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
return result.join('');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (tmp.length > 0) {
|
|
104
|
+
result[resultCnt++] = tmp;
|
|
105
|
+
resultLength += tmp.length;
|
|
106
|
+
}
|
|
107
|
+
if (resultLength >= 64 * 1024) {
|
|
108
|
+
return result.join('');
|
|
109
|
+
}
|
|
110
|
+
} while (true);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const invalidFunc = () => { throw new Error(`Invalid change accessor`); };
|
|
114
|
+
let TextModel = class TextModel extends Disposable {
|
|
115
|
+
static { TextModel_1 = this; }
|
|
116
|
+
static { this._MODEL_SYNC_LIMIT = 50 * 1024 * 1024; } // 50 MB, // used in tests
|
|
117
|
+
static { this.LARGE_FILE_SIZE_THRESHOLD = 20 * 1024 * 1024; } // 20 MB;
|
|
118
|
+
static { this.LARGE_FILE_LINE_COUNT_THRESHOLD = 300 * 1000; } // 300K lines
|
|
119
|
+
static { this.LARGE_FILE_HEAP_OPERATION_THRESHOLD = 256 * 1024 * 1024; } // 256M characters, usually ~> 512MB memory usage
|
|
120
|
+
static { this.DEFAULT_CREATION_OPTIONS = {
|
|
121
|
+
isForSimpleWidget: false,
|
|
122
|
+
tabSize: EDITOR_MODEL_DEFAULTS.tabSize,
|
|
123
|
+
indentSize: EDITOR_MODEL_DEFAULTS.indentSize,
|
|
124
|
+
insertSpaces: EDITOR_MODEL_DEFAULTS.insertSpaces,
|
|
125
|
+
detectIndentation: false,
|
|
126
|
+
defaultEOL: 1 /* model.DefaultEndOfLine.LF */,
|
|
127
|
+
trimAutoWhitespace: EDITOR_MODEL_DEFAULTS.trimAutoWhitespace,
|
|
128
|
+
largeFileOptimizations: EDITOR_MODEL_DEFAULTS.largeFileOptimizations,
|
|
129
|
+
bracketPairColorizationOptions: EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions,
|
|
130
|
+
}; }
|
|
131
|
+
static resolveOptions(textBuffer, options) {
|
|
132
|
+
if (options.detectIndentation) {
|
|
133
|
+
const guessedIndentation = guessIndentation(textBuffer, options.tabSize, options.insertSpaces);
|
|
134
|
+
return new TextModelResolvedOptions({
|
|
135
|
+
tabSize: guessedIndentation.tabSize,
|
|
136
|
+
indentSize: 'tabSize', // TODO@Alex: guess indentSize independent of tabSize
|
|
137
|
+
insertSpaces: guessedIndentation.insertSpaces,
|
|
138
|
+
trimAutoWhitespace: options.trimAutoWhitespace,
|
|
139
|
+
defaultEOL: options.defaultEOL,
|
|
140
|
+
bracketPairColorizationOptions: options.bracketPairColorizationOptions,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return new TextModelResolvedOptions(options);
|
|
144
|
+
}
|
|
145
|
+
get onDidChangeLanguage() { return this._tokenizationTextModelPart.onDidChangeLanguage; }
|
|
146
|
+
get onDidChangeLanguageConfiguration() { return this._tokenizationTextModelPart.onDidChangeLanguageConfiguration; }
|
|
147
|
+
get onDidChangeTokens() { return this._tokenizationTextModelPart.onDidChangeTokens; }
|
|
148
|
+
get onDidChangeOptions() { return this._onDidChangeOptions.event; }
|
|
149
|
+
get onDidChangeAttached() { return this._onDidChangeAttached.event; }
|
|
150
|
+
get onDidChangeLineHeight() { return this._onDidChangeLineHeight.event; }
|
|
151
|
+
get onDidChangeFont() { return this._onDidChangeFont.event; }
|
|
152
|
+
onDidChangeContent(listener) {
|
|
153
|
+
return this._eventEmitter.slowEvent((e) => listener(e.contentChangedEvent));
|
|
154
|
+
}
|
|
155
|
+
onDidChangeContentOrInjectedText(listener) {
|
|
156
|
+
return combinedDisposable(this._eventEmitter.fastEvent(e => listener(e)), this._onDidChangeInjectedText.event(e => listener(e)));
|
|
157
|
+
}
|
|
158
|
+
_isDisposing() { return this.__isDisposing; }
|
|
159
|
+
get tokenization() { return this._tokenizationTextModelPart; }
|
|
160
|
+
get bracketPairs() { return this._bracketPairs; }
|
|
161
|
+
get guides() { return this._guidesTextModelPart; }
|
|
162
|
+
constructor(source, languageIdOrSelection, creationOptions, associatedResource = null, _undoRedoService, _languageService, _languageConfigurationService, instantiationService) {
|
|
163
|
+
super();
|
|
164
|
+
this._undoRedoService = _undoRedoService;
|
|
165
|
+
this._languageService = _languageService;
|
|
166
|
+
this._languageConfigurationService = _languageConfigurationService;
|
|
167
|
+
this.instantiationService = instantiationService;
|
|
168
|
+
//#region Events
|
|
169
|
+
this._onWillDispose = this._register(new Emitter());
|
|
170
|
+
this.onWillDispose = this._onWillDispose.event;
|
|
171
|
+
this._onDidChangeDecorations = this._register(new DidChangeDecorationsEmitter((affectedInjectedTextLines, affectedLineHeights, affectedFontLines) => this.handleBeforeFireDecorationsChangedEvent(affectedInjectedTextLines, affectedLineHeights, affectedFontLines)));
|
|
172
|
+
this.onDidChangeDecorations = this._onDidChangeDecorations.event;
|
|
173
|
+
this._onDidChangeOptions = this._register(new Emitter());
|
|
174
|
+
this._onDidChangeAttached = this._register(new Emitter());
|
|
175
|
+
this._onDidChangeInjectedText = this._register(new Emitter());
|
|
176
|
+
this._onDidChangeLineHeight = this._register(new Emitter());
|
|
177
|
+
this._onDidChangeFont = this._register(new Emitter());
|
|
178
|
+
this._eventEmitter = this._register(new DidChangeContentEmitter());
|
|
179
|
+
this._languageSelectionListener = this._register(new MutableDisposable());
|
|
180
|
+
this._deltaDecorationCallCnt = 0;
|
|
181
|
+
this._attachedViews = new AttachedViews();
|
|
182
|
+
// Generate a new unique model id
|
|
183
|
+
MODEL_ID++;
|
|
184
|
+
this.id = '$model' + MODEL_ID;
|
|
185
|
+
this.isForSimpleWidget = creationOptions.isForSimpleWidget;
|
|
186
|
+
if (typeof associatedResource === 'undefined' || associatedResource === null) {
|
|
187
|
+
this._associatedResource = URI.parse('inmemory://model/' + MODEL_ID);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
this._associatedResource = associatedResource;
|
|
191
|
+
}
|
|
192
|
+
this._attachedEditorCount = 0;
|
|
193
|
+
const { textBuffer, disposable } = createTextBuffer(source, creationOptions.defaultEOL);
|
|
194
|
+
this._buffer = textBuffer;
|
|
195
|
+
this._bufferDisposable = disposable;
|
|
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._options = TextModel_1.resolveOptions(this._buffer, creationOptions);
|
|
211
|
+
const languageId = (typeof languageIdOrSelection === 'string' ? languageIdOrSelection : languageIdOrSelection.languageId);
|
|
212
|
+
if (typeof languageIdOrSelection !== 'string') {
|
|
213
|
+
this._languageSelectionListener.value = languageIdOrSelection.onDidChange(() => this._setLanguage(languageIdOrSelection.languageId));
|
|
214
|
+
}
|
|
215
|
+
this._bracketPairs = this._register(new BracketPairsTextModelPart(this, this._languageConfigurationService));
|
|
216
|
+
this._guidesTextModelPart = this._register(new GuidesTextModelPart(this, this._languageConfigurationService));
|
|
217
|
+
this._decorationProvider = this._register(new ColorizedBracketPairsDecorationProvider(this));
|
|
218
|
+
this._tokenizationTextModelPart = this.instantiationService.createInstance(TokenizationTextModelPart, this, this._bracketPairs, languageId, this._attachedViews);
|
|
219
|
+
this._isTooLargeForSyncing = (bufferTextLength > TextModel_1._MODEL_SYNC_LIMIT);
|
|
220
|
+
this._versionId = 1;
|
|
221
|
+
this._alternativeVersionId = 1;
|
|
222
|
+
this._initialUndoRedoSnapshot = null;
|
|
223
|
+
this._isDisposed = false;
|
|
224
|
+
this.__isDisposing = false;
|
|
225
|
+
this._instanceId = singleLetterHash(MODEL_ID);
|
|
226
|
+
this._lastDecorationId = 0;
|
|
227
|
+
this._decorations = Object.create(null);
|
|
228
|
+
this._decorationsTree = new DecorationsTrees();
|
|
229
|
+
this._commandManager = new EditStack(this, this._undoRedoService);
|
|
230
|
+
this._isUndoing = false;
|
|
231
|
+
this._isRedoing = false;
|
|
232
|
+
this._trimAutoWhitespaceLines = null;
|
|
233
|
+
this._register(this._decorationProvider.onDidChange(() => {
|
|
234
|
+
this._onDidChangeDecorations.beginDeferredEmit();
|
|
235
|
+
this._onDidChangeDecorations.fire();
|
|
236
|
+
this._onDidChangeDecorations.endDeferredEmit();
|
|
237
|
+
}));
|
|
238
|
+
this._languageService.requestRichLanguageFeatures(languageId);
|
|
239
|
+
this._register(this._languageConfigurationService.onDidChange(e => {
|
|
240
|
+
this._bracketPairs.handleLanguageConfigurationServiceChange(e);
|
|
241
|
+
this._tokenizationTextModelPart.handleLanguageConfigurationServiceChange(e);
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
dispose() {
|
|
245
|
+
this.__isDisposing = true;
|
|
246
|
+
this._onWillDispose.fire();
|
|
247
|
+
this._tokenizationTextModelPart.dispose();
|
|
248
|
+
this._isDisposed = true;
|
|
249
|
+
super.dispose();
|
|
250
|
+
this._bufferDisposable.dispose();
|
|
251
|
+
this.__isDisposing = false;
|
|
252
|
+
// Manually release reference to previous text buffer to avoid large leaks
|
|
253
|
+
// in case someone leaks a TextModel reference
|
|
254
|
+
const emptyDisposedTextBuffer = new PieceTreeTextBuffer([], '', '\n', false, false, true, true);
|
|
255
|
+
emptyDisposedTextBuffer.dispose();
|
|
256
|
+
this._buffer = emptyDisposedTextBuffer;
|
|
257
|
+
this._bufferDisposable = Disposable.None;
|
|
258
|
+
}
|
|
259
|
+
_assertNotDisposed() {
|
|
260
|
+
if (this._isDisposed) {
|
|
261
|
+
throw new BugIndicatingError('Model is disposed!');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
getTextBuffer() {
|
|
265
|
+
this._assertNotDisposed();
|
|
266
|
+
return this._buffer;
|
|
267
|
+
}
|
|
268
|
+
_emitContentChangedEvent(rawChange, change) {
|
|
269
|
+
if (this.__isDisposing) {
|
|
270
|
+
// Do not confuse listeners by emitting any event after disposing
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
this._tokenizationTextModelPart.handleDidChangeContent(change);
|
|
274
|
+
this._bracketPairs.handleDidChangeContent(change);
|
|
275
|
+
this._eventEmitter.fire(new InternalModelContentChangeEvent(rawChange, change));
|
|
276
|
+
}
|
|
277
|
+
setValue(value, reason = EditSources.setValue()) {
|
|
278
|
+
this._assertNotDisposed();
|
|
279
|
+
if (value === null || value === undefined) {
|
|
280
|
+
throw illegalArgument();
|
|
281
|
+
}
|
|
282
|
+
const { textBuffer, disposable } = createTextBuffer(value, this._options.defaultEOL);
|
|
283
|
+
this._setValueFromTextBuffer(textBuffer, disposable, reason);
|
|
284
|
+
}
|
|
285
|
+
_createContentChanged2(range, rangeOffset, rangeLength, rangeEndPosition, text, isUndoing, isRedoing, isFlush, isEolChange, reason) {
|
|
286
|
+
return {
|
|
287
|
+
changes: [{
|
|
288
|
+
range: range,
|
|
289
|
+
rangeOffset: rangeOffset,
|
|
290
|
+
rangeLength: rangeLength,
|
|
291
|
+
text: text,
|
|
292
|
+
}],
|
|
293
|
+
eol: this._buffer.getEOL(),
|
|
294
|
+
isEolChange: isEolChange,
|
|
295
|
+
versionId: this.getVersionId(),
|
|
296
|
+
isUndoing: isUndoing,
|
|
297
|
+
isRedoing: isRedoing,
|
|
298
|
+
isFlush: isFlush,
|
|
299
|
+
detailedReasons: [reason],
|
|
300
|
+
detailedReasonsChangeLengths: [1],
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
_setValueFromTextBuffer(textBuffer, textBufferDisposable, reason) {
|
|
304
|
+
this._assertNotDisposed();
|
|
305
|
+
const oldFullModelRange = this.getFullModelRange();
|
|
306
|
+
const oldModelValueLength = this.getValueLengthInRange(oldFullModelRange);
|
|
307
|
+
const endLineNumber = this.getLineCount();
|
|
308
|
+
const endColumn = this.getLineMaxColumn(endLineNumber);
|
|
309
|
+
this._buffer = textBuffer;
|
|
310
|
+
this._bufferDisposable.dispose();
|
|
311
|
+
this._bufferDisposable = textBufferDisposable;
|
|
312
|
+
this._increaseVersionId();
|
|
313
|
+
// Destroy all my decorations
|
|
314
|
+
this._decorations = Object.create(null);
|
|
315
|
+
this._decorationsTree = new DecorationsTrees();
|
|
316
|
+
// Destroy my edit history and settings
|
|
317
|
+
this._commandManager.clear();
|
|
318
|
+
this._trimAutoWhitespaceLines = null;
|
|
319
|
+
this._emitContentChangedEvent(new ModelRawContentChangedEvent([
|
|
320
|
+
new ModelRawFlush()
|
|
321
|
+
], this._versionId, false, false), this._createContentChanged2(new Range(1, 1, endLineNumber, endColumn), 0, oldModelValueLength, new Position(endLineNumber, endColumn), this.getValue(), false, false, true, false, reason));
|
|
322
|
+
}
|
|
323
|
+
setEOL(eol) {
|
|
324
|
+
this._assertNotDisposed();
|
|
325
|
+
const newEOL = (eol === 1 /* model.EndOfLineSequence.CRLF */ ? '\r\n' : '\n');
|
|
326
|
+
if (this._buffer.getEOL() === newEOL) {
|
|
327
|
+
// Nothing to do
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const oldFullModelRange = this.getFullModelRange();
|
|
331
|
+
const oldModelValueLength = this.getValueLengthInRange(oldFullModelRange);
|
|
332
|
+
const endLineNumber = this.getLineCount();
|
|
333
|
+
const endColumn = this.getLineMaxColumn(endLineNumber);
|
|
334
|
+
this._onBeforeEOLChange();
|
|
335
|
+
this._buffer.setEOL(newEOL);
|
|
336
|
+
this._increaseVersionId();
|
|
337
|
+
this._onAfterEOLChange();
|
|
338
|
+
this._emitContentChangedEvent(new ModelRawContentChangedEvent([
|
|
339
|
+
new ModelRawEOLChanged()
|
|
340
|
+
], this._versionId, false, false), this._createContentChanged2(new Range(1, 1, endLineNumber, endColumn), 0, oldModelValueLength, new Position(endLineNumber, endColumn), this.getValue(), false, false, false, true, EditSources.eolChange()));
|
|
341
|
+
}
|
|
342
|
+
_onBeforeEOLChange() {
|
|
343
|
+
// Ensure all decorations get their `range` set.
|
|
344
|
+
this._decorationsTree.ensureAllNodesHaveRanges(this);
|
|
345
|
+
}
|
|
346
|
+
_onAfterEOLChange() {
|
|
347
|
+
// Transform back `range` to offsets
|
|
348
|
+
const versionId = this.getVersionId();
|
|
349
|
+
const allDecorations = this._decorationsTree.collectNodesPostOrder();
|
|
350
|
+
for (let i = 0, len = allDecorations.length; i < len; i++) {
|
|
351
|
+
const node = allDecorations[i];
|
|
352
|
+
const range = node.range; // the range is defined due to `_onBeforeEOLChange`
|
|
353
|
+
const delta = node.cachedAbsoluteStart - node.start;
|
|
354
|
+
const startOffset = this._buffer.getOffsetAt(range.startLineNumber, range.startColumn);
|
|
355
|
+
const endOffset = this._buffer.getOffsetAt(range.endLineNumber, range.endColumn);
|
|
356
|
+
node.cachedAbsoluteStart = startOffset;
|
|
357
|
+
node.cachedAbsoluteEnd = endOffset;
|
|
358
|
+
node.cachedVersionId = versionId;
|
|
359
|
+
node.start = startOffset - delta;
|
|
360
|
+
node.end = endOffset - delta;
|
|
361
|
+
recomputeMaxEnd(node);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
onBeforeAttached() {
|
|
365
|
+
this._attachedEditorCount++;
|
|
366
|
+
if (this._attachedEditorCount === 1) {
|
|
367
|
+
this._tokenizationTextModelPart.handleDidChangeAttached();
|
|
368
|
+
this._onDidChangeAttached.fire(undefined);
|
|
369
|
+
}
|
|
370
|
+
return this._attachedViews.attachView();
|
|
371
|
+
}
|
|
372
|
+
onBeforeDetached(view) {
|
|
373
|
+
this._attachedEditorCount--;
|
|
374
|
+
if (this._attachedEditorCount === 0) {
|
|
375
|
+
this._tokenizationTextModelPart.handleDidChangeAttached();
|
|
376
|
+
this._onDidChangeAttached.fire(undefined);
|
|
377
|
+
}
|
|
378
|
+
this._attachedViews.detachView(view);
|
|
379
|
+
}
|
|
380
|
+
isAttachedToEditor() {
|
|
381
|
+
return this._attachedEditorCount > 0;
|
|
382
|
+
}
|
|
383
|
+
getAttachedEditorCount() {
|
|
384
|
+
return this._attachedEditorCount;
|
|
385
|
+
}
|
|
386
|
+
isTooLargeForSyncing() {
|
|
387
|
+
return this._isTooLargeForSyncing;
|
|
388
|
+
}
|
|
389
|
+
isTooLargeForTokenization() {
|
|
390
|
+
return this._isTooLargeForTokenization;
|
|
391
|
+
}
|
|
392
|
+
isTooLargeForHeapOperation() {
|
|
393
|
+
return this._isTooLargeForHeapOperation;
|
|
394
|
+
}
|
|
395
|
+
isDisposed() {
|
|
396
|
+
return this._isDisposed;
|
|
397
|
+
}
|
|
398
|
+
isDominatedByLongLines() {
|
|
399
|
+
this._assertNotDisposed();
|
|
400
|
+
if (this.isTooLargeForTokenization()) {
|
|
401
|
+
// Cannot word wrap huge files anyways, so it doesn't really matter
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
let smallLineCharCount = 0;
|
|
405
|
+
let longLineCharCount = 0;
|
|
406
|
+
const lineCount = this._buffer.getLineCount();
|
|
407
|
+
for (let lineNumber = 1; lineNumber <= lineCount; lineNumber++) {
|
|
408
|
+
const lineLength = this._buffer.getLineLength(lineNumber);
|
|
409
|
+
if (lineLength >= LONG_LINE_BOUNDARY) {
|
|
410
|
+
longLineCharCount += lineLength;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
smallLineCharCount += lineLength;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return (longLineCharCount > smallLineCharCount);
|
|
417
|
+
}
|
|
418
|
+
get uri() {
|
|
419
|
+
return this._associatedResource;
|
|
420
|
+
}
|
|
421
|
+
//#region Options
|
|
422
|
+
getOptions() {
|
|
423
|
+
this._assertNotDisposed();
|
|
424
|
+
return this._options;
|
|
425
|
+
}
|
|
426
|
+
getFormattingOptions() {
|
|
427
|
+
return {
|
|
428
|
+
tabSize: this._options.indentSize,
|
|
429
|
+
insertSpaces: this._options.insertSpaces
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
updateOptions(_newOpts) {
|
|
433
|
+
this._assertNotDisposed();
|
|
434
|
+
const tabSize = (typeof _newOpts.tabSize !== 'undefined') ? _newOpts.tabSize : this._options.tabSize;
|
|
435
|
+
const indentSize = (typeof _newOpts.indentSize !== 'undefined') ? _newOpts.indentSize : this._options.originalIndentSize;
|
|
436
|
+
const insertSpaces = (typeof _newOpts.insertSpaces !== 'undefined') ? _newOpts.insertSpaces : this._options.insertSpaces;
|
|
437
|
+
const trimAutoWhitespace = (typeof _newOpts.trimAutoWhitespace !== 'undefined') ? _newOpts.trimAutoWhitespace : this._options.trimAutoWhitespace;
|
|
438
|
+
const bracketPairColorizationOptions = (typeof _newOpts.bracketColorizationOptions !== 'undefined') ? _newOpts.bracketColorizationOptions : this._options.bracketPairColorizationOptions;
|
|
439
|
+
const newOpts = new TextModelResolvedOptions({
|
|
440
|
+
tabSize: tabSize,
|
|
441
|
+
indentSize: indentSize,
|
|
442
|
+
insertSpaces: insertSpaces,
|
|
443
|
+
defaultEOL: this._options.defaultEOL,
|
|
444
|
+
trimAutoWhitespace: trimAutoWhitespace,
|
|
445
|
+
bracketPairColorizationOptions,
|
|
446
|
+
});
|
|
447
|
+
if (this._options.equals(newOpts)) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
const e = this._options.createChangeEvent(newOpts);
|
|
451
|
+
this._options = newOpts;
|
|
452
|
+
this._bracketPairs.handleDidChangeOptions(e);
|
|
453
|
+
this._decorationProvider.handleDidChangeOptions(e);
|
|
454
|
+
this._onDidChangeOptions.fire(e);
|
|
455
|
+
}
|
|
456
|
+
detectIndentation(defaultInsertSpaces, defaultTabSize) {
|
|
457
|
+
this._assertNotDisposed();
|
|
458
|
+
const guessedIndentation = guessIndentation(this._buffer, defaultTabSize, defaultInsertSpaces);
|
|
459
|
+
this.updateOptions({
|
|
460
|
+
insertSpaces: guessedIndentation.insertSpaces,
|
|
461
|
+
tabSize: guessedIndentation.tabSize,
|
|
462
|
+
indentSize: guessedIndentation.tabSize, // TODO@Alex: guess indentSize independent of tabSize
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
normalizeIndentation(str) {
|
|
466
|
+
this._assertNotDisposed();
|
|
467
|
+
return normalizeIndentation(str, this._options.indentSize, this._options.insertSpaces);
|
|
468
|
+
}
|
|
469
|
+
//#endregion
|
|
470
|
+
//#region Reading
|
|
471
|
+
getVersionId() {
|
|
472
|
+
this._assertNotDisposed();
|
|
473
|
+
return this._versionId;
|
|
474
|
+
}
|
|
475
|
+
mightContainRTL() {
|
|
476
|
+
return this._buffer.mightContainRTL();
|
|
477
|
+
}
|
|
478
|
+
mightContainUnusualLineTerminators() {
|
|
479
|
+
return this._buffer.mightContainUnusualLineTerminators();
|
|
480
|
+
}
|
|
481
|
+
removeUnusualLineTerminators(selections = null) {
|
|
482
|
+
const matches = this.findMatches(UNUSUAL_LINE_TERMINATORS.source, false, true, false, null, false, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */);
|
|
483
|
+
this._buffer.resetMightContainUnusualLineTerminators();
|
|
484
|
+
this.pushEditOperations(selections, matches.map(m => ({ range: m.range, text: null })), () => null);
|
|
485
|
+
}
|
|
486
|
+
mightContainNonBasicASCII() {
|
|
487
|
+
return this._buffer.mightContainNonBasicASCII();
|
|
488
|
+
}
|
|
489
|
+
getAlternativeVersionId() {
|
|
490
|
+
this._assertNotDisposed();
|
|
491
|
+
return this._alternativeVersionId;
|
|
492
|
+
}
|
|
493
|
+
getInitialUndoRedoSnapshot() {
|
|
494
|
+
this._assertNotDisposed();
|
|
495
|
+
return this._initialUndoRedoSnapshot;
|
|
496
|
+
}
|
|
497
|
+
getOffsetAt(rawPosition) {
|
|
498
|
+
this._assertNotDisposed();
|
|
499
|
+
const position = this._validatePosition(rawPosition.lineNumber, rawPosition.column, 0 /* StringOffsetValidationType.Relaxed */);
|
|
500
|
+
return this._buffer.getOffsetAt(position.lineNumber, position.column);
|
|
501
|
+
}
|
|
502
|
+
getPositionAt(rawOffset) {
|
|
503
|
+
this._assertNotDisposed();
|
|
504
|
+
const offset = (Math.min(this._buffer.getLength(), Math.max(0, rawOffset)));
|
|
505
|
+
return this._buffer.getPositionAt(offset);
|
|
506
|
+
}
|
|
507
|
+
_increaseVersionId() {
|
|
508
|
+
this._versionId = this._versionId + 1;
|
|
509
|
+
this._alternativeVersionId = this._versionId;
|
|
510
|
+
}
|
|
511
|
+
_overwriteVersionId(versionId) {
|
|
512
|
+
this._versionId = versionId;
|
|
513
|
+
}
|
|
514
|
+
_overwriteAlternativeVersionId(newAlternativeVersionId) {
|
|
515
|
+
this._alternativeVersionId = newAlternativeVersionId;
|
|
516
|
+
}
|
|
517
|
+
_overwriteInitialUndoRedoSnapshot(newInitialUndoRedoSnapshot) {
|
|
518
|
+
this._initialUndoRedoSnapshot = newInitialUndoRedoSnapshot;
|
|
519
|
+
}
|
|
520
|
+
getValue(eol, preserveBOM = false) {
|
|
521
|
+
this._assertNotDisposed();
|
|
522
|
+
if (this.isTooLargeForHeapOperation()) {
|
|
523
|
+
throw new BugIndicatingError('Operation would exceed heap memory limits');
|
|
524
|
+
}
|
|
525
|
+
const fullModelRange = this.getFullModelRange();
|
|
526
|
+
const fullModelValue = this.getValueInRange(fullModelRange, eol);
|
|
527
|
+
if (preserveBOM) {
|
|
528
|
+
return this._buffer.getBOM() + fullModelValue;
|
|
529
|
+
}
|
|
530
|
+
return fullModelValue;
|
|
531
|
+
}
|
|
532
|
+
createSnapshot(preserveBOM = false) {
|
|
533
|
+
return new TextModelSnapshot(this._buffer.createSnapshot(preserveBOM));
|
|
534
|
+
}
|
|
535
|
+
getValueLength(eol, preserveBOM = false) {
|
|
536
|
+
this._assertNotDisposed();
|
|
537
|
+
const fullModelRange = this.getFullModelRange();
|
|
538
|
+
const fullModelValue = this.getValueLengthInRange(fullModelRange, eol);
|
|
539
|
+
if (preserveBOM) {
|
|
540
|
+
return this._buffer.getBOM().length + fullModelValue;
|
|
541
|
+
}
|
|
542
|
+
return fullModelValue;
|
|
543
|
+
}
|
|
544
|
+
getValueInRange(rawRange, eol = 0 /* model.EndOfLinePreference.TextDefined */) {
|
|
545
|
+
this._assertNotDisposed();
|
|
546
|
+
return this._buffer.getValueInRange(this.validateRange(rawRange), eol);
|
|
547
|
+
}
|
|
548
|
+
getValueLengthInRange(rawRange, eol = 0 /* model.EndOfLinePreference.TextDefined */) {
|
|
549
|
+
this._assertNotDisposed();
|
|
550
|
+
return this._buffer.getValueLengthInRange(this.validateRange(rawRange), eol);
|
|
551
|
+
}
|
|
552
|
+
getCharacterCountInRange(rawRange, eol = 0 /* model.EndOfLinePreference.TextDefined */) {
|
|
553
|
+
this._assertNotDisposed();
|
|
554
|
+
return this._buffer.getCharacterCountInRange(this.validateRange(rawRange), eol);
|
|
555
|
+
}
|
|
556
|
+
getLineCount() {
|
|
557
|
+
this._assertNotDisposed();
|
|
558
|
+
return this._buffer.getLineCount();
|
|
559
|
+
}
|
|
560
|
+
getLineContent(lineNumber) {
|
|
561
|
+
this._assertNotDisposed();
|
|
562
|
+
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
|
|
563
|
+
throw new BugIndicatingError('Illegal value for lineNumber');
|
|
564
|
+
}
|
|
565
|
+
return this._buffer.getLineContent(lineNumber);
|
|
566
|
+
}
|
|
567
|
+
getLineLength(lineNumber) {
|
|
568
|
+
this._assertNotDisposed();
|
|
569
|
+
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
|
|
570
|
+
throw new BugIndicatingError('Illegal value for lineNumber');
|
|
571
|
+
}
|
|
572
|
+
return this._buffer.getLineLength(lineNumber);
|
|
573
|
+
}
|
|
574
|
+
getLinesContent() {
|
|
575
|
+
this._assertNotDisposed();
|
|
576
|
+
if (this.isTooLargeForHeapOperation()) {
|
|
577
|
+
throw new BugIndicatingError('Operation would exceed heap memory limits');
|
|
578
|
+
}
|
|
579
|
+
return this._buffer.getLinesContent();
|
|
580
|
+
}
|
|
581
|
+
getEOL() {
|
|
582
|
+
this._assertNotDisposed();
|
|
583
|
+
return this._buffer.getEOL();
|
|
584
|
+
}
|
|
585
|
+
getEndOfLineSequence() {
|
|
586
|
+
this._assertNotDisposed();
|
|
587
|
+
return (this._buffer.getEOL() === '\n'
|
|
588
|
+
? 0 /* model.EndOfLineSequence.LF */
|
|
589
|
+
: 1 /* model.EndOfLineSequence.CRLF */);
|
|
590
|
+
}
|
|
591
|
+
getLineMinColumn(lineNumber) {
|
|
592
|
+
this._assertNotDisposed();
|
|
593
|
+
return 1;
|
|
594
|
+
}
|
|
595
|
+
getLineMaxColumn(lineNumber) {
|
|
596
|
+
this._assertNotDisposed();
|
|
597
|
+
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
|
|
598
|
+
throw new BugIndicatingError('Illegal value for lineNumber');
|
|
599
|
+
}
|
|
600
|
+
return this._buffer.getLineLength(lineNumber) + 1;
|
|
601
|
+
}
|
|
602
|
+
getLineFirstNonWhitespaceColumn(lineNumber) {
|
|
603
|
+
this._assertNotDisposed();
|
|
604
|
+
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
|
|
605
|
+
throw new BugIndicatingError('Illegal value for lineNumber');
|
|
606
|
+
}
|
|
607
|
+
return this._buffer.getLineFirstNonWhitespaceColumn(lineNumber);
|
|
608
|
+
}
|
|
609
|
+
getLineLastNonWhitespaceColumn(lineNumber) {
|
|
610
|
+
this._assertNotDisposed();
|
|
611
|
+
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
|
|
612
|
+
throw new BugIndicatingError('Illegal value for lineNumber');
|
|
613
|
+
}
|
|
614
|
+
return this._buffer.getLineLastNonWhitespaceColumn(lineNumber);
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Validates `range` is within buffer bounds, but allows it to sit in between surrogate pairs, etc.
|
|
618
|
+
* Will try to not allocate if possible.
|
|
619
|
+
*/
|
|
620
|
+
_validateRangeRelaxedNoAllocations(range) {
|
|
621
|
+
const linesCount = this._buffer.getLineCount();
|
|
622
|
+
const initialStartLineNumber = range.startLineNumber;
|
|
623
|
+
const initialStartColumn = range.startColumn;
|
|
624
|
+
let startLineNumber = Math.floor((typeof initialStartLineNumber === 'number' && !isNaN(initialStartLineNumber)) ? initialStartLineNumber : 1);
|
|
625
|
+
let startColumn = Math.floor((typeof initialStartColumn === 'number' && !isNaN(initialStartColumn)) ? initialStartColumn : 1);
|
|
626
|
+
if (startLineNumber < 1) {
|
|
627
|
+
startLineNumber = 1;
|
|
628
|
+
startColumn = 1;
|
|
629
|
+
}
|
|
630
|
+
else if (startLineNumber > linesCount) {
|
|
631
|
+
startLineNumber = linesCount;
|
|
632
|
+
startColumn = this.getLineMaxColumn(startLineNumber);
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
if (startColumn <= 1) {
|
|
636
|
+
startColumn = 1;
|
|
637
|
+
}
|
|
638
|
+
else {
|
|
639
|
+
const maxColumn = this.getLineMaxColumn(startLineNumber);
|
|
640
|
+
if (startColumn >= maxColumn) {
|
|
641
|
+
startColumn = maxColumn;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
const initialEndLineNumber = range.endLineNumber;
|
|
646
|
+
const initialEndColumn = range.endColumn;
|
|
647
|
+
let endLineNumber = Math.floor((typeof initialEndLineNumber === 'number' && !isNaN(initialEndLineNumber)) ? initialEndLineNumber : 1);
|
|
648
|
+
let endColumn = Math.floor((typeof initialEndColumn === 'number' && !isNaN(initialEndColumn)) ? initialEndColumn : 1);
|
|
649
|
+
if (endLineNumber < 1) {
|
|
650
|
+
endLineNumber = 1;
|
|
651
|
+
endColumn = 1;
|
|
652
|
+
}
|
|
653
|
+
else if (endLineNumber > linesCount) {
|
|
654
|
+
endLineNumber = linesCount;
|
|
655
|
+
endColumn = this.getLineMaxColumn(endLineNumber);
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
if (endColumn <= 1) {
|
|
659
|
+
endColumn = 1;
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
const maxColumn = this.getLineMaxColumn(endLineNumber);
|
|
663
|
+
if (endColumn >= maxColumn) {
|
|
664
|
+
endColumn = maxColumn;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
if (initialStartLineNumber === startLineNumber
|
|
669
|
+
&& initialStartColumn === startColumn
|
|
670
|
+
&& initialEndLineNumber === endLineNumber
|
|
671
|
+
&& initialEndColumn === endColumn
|
|
672
|
+
&& range instanceof Range
|
|
673
|
+
&& !(range instanceof Selection)) {
|
|
674
|
+
return range;
|
|
675
|
+
}
|
|
676
|
+
return new Range(startLineNumber, startColumn, endLineNumber, endColumn);
|
|
677
|
+
}
|
|
678
|
+
_isValidPosition(lineNumber, column, validationType) {
|
|
679
|
+
if (typeof lineNumber !== 'number' || typeof column !== 'number') {
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
if (isNaN(lineNumber) || isNaN(column)) {
|
|
683
|
+
return false;
|
|
684
|
+
}
|
|
685
|
+
if (lineNumber < 1 || column < 1) {
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
if ((lineNumber | 0) !== lineNumber || (column | 0) !== column) {
|
|
689
|
+
return false;
|
|
690
|
+
}
|
|
691
|
+
const lineCount = this._buffer.getLineCount();
|
|
692
|
+
if (lineNumber > lineCount) {
|
|
693
|
+
return false;
|
|
694
|
+
}
|
|
695
|
+
if (column === 1) {
|
|
696
|
+
return true;
|
|
697
|
+
}
|
|
698
|
+
const maxColumn = this.getLineMaxColumn(lineNumber);
|
|
699
|
+
if (column > maxColumn) {
|
|
700
|
+
return false;
|
|
701
|
+
}
|
|
702
|
+
if (validationType === 1 /* StringOffsetValidationType.SurrogatePairs */) {
|
|
703
|
+
// !!At this point, column > 1
|
|
704
|
+
const charCodeBefore = this._buffer.getLineCharCode(lineNumber, column - 2);
|
|
705
|
+
if (isHighSurrogate(charCodeBefore)) {
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return true;
|
|
710
|
+
}
|
|
711
|
+
_validatePosition(_lineNumber, _column, validationType) {
|
|
712
|
+
const lineNumber = Math.floor((typeof _lineNumber === 'number' && !isNaN(_lineNumber)) ? _lineNumber : 1);
|
|
713
|
+
const column = Math.floor((typeof _column === 'number' && !isNaN(_column)) ? _column : 1);
|
|
714
|
+
const lineCount = this._buffer.getLineCount();
|
|
715
|
+
if (lineNumber < 1) {
|
|
716
|
+
return new Position(1, 1);
|
|
717
|
+
}
|
|
718
|
+
if (lineNumber > lineCount) {
|
|
719
|
+
return new Position(lineCount, this.getLineMaxColumn(lineCount));
|
|
720
|
+
}
|
|
721
|
+
if (column <= 1) {
|
|
722
|
+
return new Position(lineNumber, 1);
|
|
723
|
+
}
|
|
724
|
+
const maxColumn = this.getLineMaxColumn(lineNumber);
|
|
725
|
+
if (column >= maxColumn) {
|
|
726
|
+
return new Position(lineNumber, maxColumn);
|
|
727
|
+
}
|
|
728
|
+
if (validationType === 1 /* StringOffsetValidationType.SurrogatePairs */) {
|
|
729
|
+
// If the position would end up in the middle of a high-low surrogate pair,
|
|
730
|
+
// we move it to before the pair
|
|
731
|
+
// !!At this point, column > 1
|
|
732
|
+
const charCodeBefore = this._buffer.getLineCharCode(lineNumber, column - 2);
|
|
733
|
+
if (isHighSurrogate(charCodeBefore)) {
|
|
734
|
+
return new Position(lineNumber, column - 1);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
return new Position(lineNumber, column);
|
|
738
|
+
}
|
|
739
|
+
validatePosition(position) {
|
|
740
|
+
const validationType = 1 /* StringOffsetValidationType.SurrogatePairs */;
|
|
741
|
+
this._assertNotDisposed();
|
|
742
|
+
// Avoid object allocation and cover most likely case
|
|
743
|
+
if (position instanceof Position) {
|
|
744
|
+
if (this._isValidPosition(position.lineNumber, position.column, validationType)) {
|
|
745
|
+
return position;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
return this._validatePosition(position.lineNumber, position.column, validationType);
|
|
749
|
+
}
|
|
750
|
+
isValidRange(range) {
|
|
751
|
+
return this._isValidRange(range, 1 /* StringOffsetValidationType.SurrogatePairs */);
|
|
752
|
+
}
|
|
753
|
+
_isValidRange(range, validationType) {
|
|
754
|
+
const startLineNumber = range.startLineNumber;
|
|
755
|
+
const startColumn = range.startColumn;
|
|
756
|
+
const endLineNumber = range.endLineNumber;
|
|
757
|
+
const endColumn = range.endColumn;
|
|
758
|
+
if (!this._isValidPosition(startLineNumber, startColumn, 0 /* StringOffsetValidationType.Relaxed */)) {
|
|
759
|
+
return false;
|
|
760
|
+
}
|
|
761
|
+
if (!this._isValidPosition(endLineNumber, endColumn, 0 /* StringOffsetValidationType.Relaxed */)) {
|
|
762
|
+
return false;
|
|
763
|
+
}
|
|
764
|
+
if (validationType === 1 /* StringOffsetValidationType.SurrogatePairs */) {
|
|
765
|
+
const charCodeBeforeStart = (startColumn > 1 ? this._buffer.getLineCharCode(startLineNumber, startColumn - 2) : 0);
|
|
766
|
+
const charCodeBeforeEnd = (endColumn > 1 && endColumn <= this._buffer.getLineLength(endLineNumber) ? this._buffer.getLineCharCode(endLineNumber, endColumn - 2) : 0);
|
|
767
|
+
const startInsideSurrogatePair = isHighSurrogate(charCodeBeforeStart);
|
|
768
|
+
const endInsideSurrogatePair = isHighSurrogate(charCodeBeforeEnd);
|
|
769
|
+
if (!startInsideSurrogatePair && !endInsideSurrogatePair) {
|
|
770
|
+
return true;
|
|
771
|
+
}
|
|
772
|
+
return false;
|
|
773
|
+
}
|
|
774
|
+
return true;
|
|
775
|
+
}
|
|
776
|
+
validateRange(_range) {
|
|
777
|
+
const validationType = 1 /* StringOffsetValidationType.SurrogatePairs */;
|
|
778
|
+
this._assertNotDisposed();
|
|
779
|
+
// Avoid object allocation and cover most likely case
|
|
780
|
+
if ((_range instanceof Range) && !(_range instanceof Selection)) {
|
|
781
|
+
if (this._isValidRange(_range, validationType)) {
|
|
782
|
+
return _range;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
const start = this._validatePosition(_range.startLineNumber, _range.startColumn, 0 /* StringOffsetValidationType.Relaxed */);
|
|
786
|
+
const end = this._validatePosition(_range.endLineNumber, _range.endColumn, 0 /* StringOffsetValidationType.Relaxed */);
|
|
787
|
+
const startLineNumber = start.lineNumber;
|
|
788
|
+
const startColumn = start.column;
|
|
789
|
+
const endLineNumber = end.lineNumber;
|
|
790
|
+
const endColumn = end.column;
|
|
791
|
+
{
|
|
792
|
+
const charCodeBeforeStart = (startColumn > 1 ? this._buffer.getLineCharCode(startLineNumber, startColumn - 2) : 0);
|
|
793
|
+
const charCodeBeforeEnd = (endColumn > 1 && endColumn <= this._buffer.getLineLength(endLineNumber) ? this._buffer.getLineCharCode(endLineNumber, endColumn - 2) : 0);
|
|
794
|
+
const startInsideSurrogatePair = isHighSurrogate(charCodeBeforeStart);
|
|
795
|
+
const endInsideSurrogatePair = isHighSurrogate(charCodeBeforeEnd);
|
|
796
|
+
if (!startInsideSurrogatePair && !endInsideSurrogatePair) {
|
|
797
|
+
return new Range(startLineNumber, startColumn, endLineNumber, endColumn);
|
|
798
|
+
}
|
|
799
|
+
if (startLineNumber === endLineNumber && startColumn === endColumn) {
|
|
800
|
+
// do not expand a collapsed range, simply move it to a valid location
|
|
801
|
+
return new Range(startLineNumber, startColumn - 1, endLineNumber, endColumn - 1);
|
|
802
|
+
}
|
|
803
|
+
if (startInsideSurrogatePair && endInsideSurrogatePair) {
|
|
804
|
+
// expand range at both ends
|
|
805
|
+
return new Range(startLineNumber, startColumn - 1, endLineNumber, endColumn + 1);
|
|
806
|
+
}
|
|
807
|
+
if (startInsideSurrogatePair) {
|
|
808
|
+
// only expand range at the start
|
|
809
|
+
return new Range(startLineNumber, startColumn - 1, endLineNumber, endColumn);
|
|
810
|
+
}
|
|
811
|
+
// only expand range at the end
|
|
812
|
+
return new Range(startLineNumber, startColumn, endLineNumber, endColumn + 1);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
modifyPosition(rawPosition, offset) {
|
|
816
|
+
this._assertNotDisposed();
|
|
817
|
+
const candidate = this.getOffsetAt(rawPosition) + offset;
|
|
818
|
+
return this.getPositionAt(Math.min(this._buffer.getLength(), Math.max(0, candidate)));
|
|
819
|
+
}
|
|
820
|
+
getFullModelRange() {
|
|
821
|
+
this._assertNotDisposed();
|
|
822
|
+
const lineCount = this.getLineCount();
|
|
823
|
+
return new Range(1, 1, lineCount, this.getLineMaxColumn(lineCount));
|
|
824
|
+
}
|
|
825
|
+
findMatchesLineByLine(searchRange, searchData, captureMatches, limitResultCount) {
|
|
826
|
+
return this._buffer.findMatchesLineByLine(searchRange, searchData, captureMatches, limitResultCount);
|
|
827
|
+
}
|
|
828
|
+
findMatches(searchString, rawSearchScope, isRegex, matchCase, wordSeparators, captureMatches, limitResultCount = LIMIT_FIND_COUNT) {
|
|
829
|
+
this._assertNotDisposed();
|
|
830
|
+
let searchRanges = null;
|
|
831
|
+
if (rawSearchScope !== null && typeof rawSearchScope !== 'boolean') {
|
|
832
|
+
if (!Array.isArray(rawSearchScope)) {
|
|
833
|
+
rawSearchScope = [rawSearchScope];
|
|
834
|
+
}
|
|
835
|
+
if (rawSearchScope.every((searchScope) => Range.isIRange(searchScope))) {
|
|
836
|
+
searchRanges = rawSearchScope.map((searchScope) => this.validateRange(searchScope));
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
if (searchRanges === null) {
|
|
840
|
+
searchRanges = [this.getFullModelRange()];
|
|
841
|
+
}
|
|
842
|
+
searchRanges = searchRanges.sort((d1, d2) => d1.startLineNumber - d2.startLineNumber || d1.startColumn - d2.startColumn);
|
|
843
|
+
const uniqueSearchRanges = [];
|
|
844
|
+
uniqueSearchRanges.push(searchRanges.reduce((prev, curr) => {
|
|
845
|
+
if (Range.areIntersecting(prev, curr)) {
|
|
846
|
+
return prev.plusRange(curr);
|
|
847
|
+
}
|
|
848
|
+
uniqueSearchRanges.push(prev);
|
|
849
|
+
return curr;
|
|
850
|
+
}));
|
|
851
|
+
let matchMapper;
|
|
852
|
+
if (!isRegex && searchString.indexOf('\n') < 0) {
|
|
853
|
+
// not regex, not multi line
|
|
854
|
+
const searchParams = new SearchParams(searchString, isRegex, matchCase, wordSeparators);
|
|
855
|
+
const searchData = searchParams.parseSearchRequest();
|
|
856
|
+
if (!searchData) {
|
|
857
|
+
return [];
|
|
858
|
+
}
|
|
859
|
+
matchMapper = (searchRange) => this.findMatchesLineByLine(searchRange, searchData, captureMatches, limitResultCount);
|
|
860
|
+
}
|
|
861
|
+
else {
|
|
862
|
+
matchMapper = (searchRange) => TextModelSearch.findMatches(this, new SearchParams(searchString, isRegex, matchCase, wordSeparators), searchRange, captureMatches, limitResultCount);
|
|
863
|
+
}
|
|
864
|
+
return uniqueSearchRanges.map(matchMapper).reduce((arr, matches) => arr.concat(matches), []);
|
|
865
|
+
}
|
|
866
|
+
findNextMatch(searchString, rawSearchStart, isRegex, matchCase, wordSeparators, captureMatches) {
|
|
867
|
+
this._assertNotDisposed();
|
|
868
|
+
const searchStart = this.validatePosition(rawSearchStart);
|
|
869
|
+
if (!isRegex && searchString.indexOf('\n') < 0) {
|
|
870
|
+
const searchParams = new SearchParams(searchString, isRegex, matchCase, wordSeparators);
|
|
871
|
+
const searchData = searchParams.parseSearchRequest();
|
|
872
|
+
if (!searchData) {
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
const lineCount = this.getLineCount();
|
|
876
|
+
let searchRange = new Range(searchStart.lineNumber, searchStart.column, lineCount, this.getLineMaxColumn(lineCount));
|
|
877
|
+
let ret = this.findMatchesLineByLine(searchRange, searchData, captureMatches, 1);
|
|
878
|
+
TextModelSearch.findNextMatch(this, new SearchParams(searchString, isRegex, matchCase, wordSeparators), searchStart, captureMatches);
|
|
879
|
+
if (ret.length > 0) {
|
|
880
|
+
return ret[0];
|
|
881
|
+
}
|
|
882
|
+
searchRange = new Range(1, 1, searchStart.lineNumber, this.getLineMaxColumn(searchStart.lineNumber));
|
|
883
|
+
ret = this.findMatchesLineByLine(searchRange, searchData, captureMatches, 1);
|
|
884
|
+
if (ret.length > 0) {
|
|
885
|
+
return ret[0];
|
|
886
|
+
}
|
|
887
|
+
return null;
|
|
888
|
+
}
|
|
889
|
+
return TextModelSearch.findNextMatch(this, new SearchParams(searchString, isRegex, matchCase, wordSeparators), searchStart, captureMatches);
|
|
890
|
+
}
|
|
891
|
+
findPreviousMatch(searchString, rawSearchStart, isRegex, matchCase, wordSeparators, captureMatches) {
|
|
892
|
+
this._assertNotDisposed();
|
|
893
|
+
const searchStart = this.validatePosition(rawSearchStart);
|
|
894
|
+
return TextModelSearch.findPreviousMatch(this, new SearchParams(searchString, isRegex, matchCase, wordSeparators), searchStart, captureMatches);
|
|
895
|
+
}
|
|
896
|
+
//#endregion
|
|
897
|
+
//#region Editing
|
|
898
|
+
pushStackElement() {
|
|
899
|
+
this._commandManager.pushStackElement();
|
|
900
|
+
}
|
|
901
|
+
popStackElement() {
|
|
902
|
+
this._commandManager.popStackElement();
|
|
903
|
+
}
|
|
904
|
+
pushEOL(eol) {
|
|
905
|
+
const currentEOL = (this.getEOL() === '\n' ? 0 /* model.EndOfLineSequence.LF */ : 1 /* model.EndOfLineSequence.CRLF */);
|
|
906
|
+
if (currentEOL === eol) {
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
try {
|
|
910
|
+
this._onDidChangeDecorations.beginDeferredEmit();
|
|
911
|
+
this._eventEmitter.beginDeferredEmit();
|
|
912
|
+
if (this._initialUndoRedoSnapshot === null) {
|
|
913
|
+
this._initialUndoRedoSnapshot = this._undoRedoService.createSnapshot(this.uri);
|
|
914
|
+
}
|
|
915
|
+
this._commandManager.pushEOL(eol);
|
|
916
|
+
}
|
|
917
|
+
finally {
|
|
918
|
+
this._eventEmitter.endDeferredEmit();
|
|
919
|
+
this._onDidChangeDecorations.endDeferredEmit();
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
_validateEditOperation(rawOperation) {
|
|
923
|
+
if (rawOperation instanceof ValidAnnotatedEditOperation) {
|
|
924
|
+
return rawOperation;
|
|
925
|
+
}
|
|
926
|
+
return new ValidAnnotatedEditOperation(rawOperation.identifier || null, this.validateRange(rawOperation.range), rawOperation.text, rawOperation.forceMoveMarkers || false, rawOperation.isAutoWhitespaceEdit || false, rawOperation._isTracked || false);
|
|
927
|
+
}
|
|
928
|
+
_validateEditOperations(rawOperations) {
|
|
929
|
+
const result = [];
|
|
930
|
+
for (let i = 0, len = rawOperations.length; i < len; i++) {
|
|
931
|
+
result[i] = this._validateEditOperation(rawOperations[i]);
|
|
932
|
+
}
|
|
933
|
+
return result;
|
|
934
|
+
}
|
|
935
|
+
pushEditOperations(beforeCursorState, editOperations, cursorStateComputer, group, reason) {
|
|
936
|
+
try {
|
|
937
|
+
this._onDidChangeDecorations.beginDeferredEmit();
|
|
938
|
+
this._eventEmitter.beginDeferredEmit();
|
|
939
|
+
return this._pushEditOperations(beforeCursorState, this._validateEditOperations(editOperations), cursorStateComputer, group, reason);
|
|
940
|
+
}
|
|
941
|
+
finally {
|
|
942
|
+
this._eventEmitter.endDeferredEmit();
|
|
943
|
+
this._onDidChangeDecorations.endDeferredEmit();
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
_pushEditOperations(beforeCursorState, editOperations, cursorStateComputer, group, reason) {
|
|
947
|
+
if (this._options.trimAutoWhitespace && this._trimAutoWhitespaceLines) {
|
|
948
|
+
// Go through each saved line number and insert a trim whitespace edit
|
|
949
|
+
// if it is safe to do so (no conflicts with other edits).
|
|
950
|
+
const incomingEdits = editOperations.map((op) => {
|
|
951
|
+
return {
|
|
952
|
+
range: this.validateRange(op.range),
|
|
953
|
+
text: op.text
|
|
954
|
+
};
|
|
955
|
+
});
|
|
956
|
+
// Sometimes, auto-formatters change ranges automatically which can cause undesired auto whitespace trimming near the cursor
|
|
957
|
+
// We'll use the following heuristic: if the edits occur near the cursor, then it's ok to trim auto whitespace
|
|
958
|
+
let editsAreNearCursors = true;
|
|
959
|
+
if (beforeCursorState) {
|
|
960
|
+
for (let i = 0, len = beforeCursorState.length; i < len; i++) {
|
|
961
|
+
const sel = beforeCursorState[i];
|
|
962
|
+
let foundEditNearSel = false;
|
|
963
|
+
for (let j = 0, lenJ = incomingEdits.length; j < lenJ; j++) {
|
|
964
|
+
const editRange = incomingEdits[j].range;
|
|
965
|
+
const selIsAbove = editRange.startLineNumber > sel.endLineNumber;
|
|
966
|
+
const selIsBelow = sel.startLineNumber > editRange.endLineNumber;
|
|
967
|
+
if (!selIsAbove && !selIsBelow) {
|
|
968
|
+
foundEditNearSel = true;
|
|
969
|
+
break;
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
if (!foundEditNearSel) {
|
|
973
|
+
editsAreNearCursors = false;
|
|
974
|
+
break;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
if (editsAreNearCursors) {
|
|
979
|
+
for (let i = 0, len = this._trimAutoWhitespaceLines.length; i < len; i++) {
|
|
980
|
+
const trimLineNumber = this._trimAutoWhitespaceLines[i];
|
|
981
|
+
const maxLineColumn = this.getLineMaxColumn(trimLineNumber);
|
|
982
|
+
let allowTrimLine = true;
|
|
983
|
+
for (let j = 0, lenJ = incomingEdits.length; j < lenJ; j++) {
|
|
984
|
+
const editRange = incomingEdits[j].range;
|
|
985
|
+
const editText = incomingEdits[j].text;
|
|
986
|
+
if (trimLineNumber < editRange.startLineNumber || trimLineNumber > editRange.endLineNumber) {
|
|
987
|
+
// `trimLine` is completely outside this edit
|
|
988
|
+
continue;
|
|
989
|
+
}
|
|
990
|
+
// At this point:
|
|
991
|
+
// editRange.startLineNumber <= trimLine <= editRange.endLineNumber
|
|
992
|
+
if (trimLineNumber === editRange.startLineNumber && editRange.startColumn === maxLineColumn
|
|
993
|
+
&& editRange.isEmpty() && editText && editText.length > 0 && editText.charAt(0) === '\n') {
|
|
994
|
+
// This edit inserts a new line (and maybe other text) after `trimLine`
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
997
|
+
if (trimLineNumber === editRange.startLineNumber && editRange.startColumn === 1
|
|
998
|
+
&& editRange.isEmpty() && editText && editText.length > 0 && editText.charAt(editText.length - 1) === '\n') {
|
|
999
|
+
// This edit inserts a new line (and maybe other text) before `trimLine`
|
|
1000
|
+
continue;
|
|
1001
|
+
}
|
|
1002
|
+
// Looks like we can't trim this line as it would interfere with an incoming edit
|
|
1003
|
+
allowTrimLine = false;
|
|
1004
|
+
break;
|
|
1005
|
+
}
|
|
1006
|
+
if (allowTrimLine) {
|
|
1007
|
+
const trimRange = new Range(trimLineNumber, 1, trimLineNumber, maxLineColumn);
|
|
1008
|
+
editOperations.push(new ValidAnnotatedEditOperation(null, trimRange, null, false, false, false));
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
this._trimAutoWhitespaceLines = null;
|
|
1013
|
+
}
|
|
1014
|
+
if (this._initialUndoRedoSnapshot === null) {
|
|
1015
|
+
this._initialUndoRedoSnapshot = this._undoRedoService.createSnapshot(this.uri);
|
|
1016
|
+
}
|
|
1017
|
+
return this._commandManager.pushEditOperation(beforeCursorState, editOperations, cursorStateComputer, group, reason);
|
|
1018
|
+
}
|
|
1019
|
+
_applyUndo(changes, eol, resultingAlternativeVersionId, resultingSelection) {
|
|
1020
|
+
const edits = changes.map((change) => {
|
|
1021
|
+
const rangeStart = this.getPositionAt(change.newPosition);
|
|
1022
|
+
const rangeEnd = this.getPositionAt(change.newEnd);
|
|
1023
|
+
return {
|
|
1024
|
+
range: new Range(rangeStart.lineNumber, rangeStart.column, rangeEnd.lineNumber, rangeEnd.column),
|
|
1025
|
+
text: change.oldText
|
|
1026
|
+
};
|
|
1027
|
+
});
|
|
1028
|
+
this._applyUndoRedoEdits(edits, eol, true, false, resultingAlternativeVersionId, resultingSelection);
|
|
1029
|
+
}
|
|
1030
|
+
_applyRedo(changes, eol, resultingAlternativeVersionId, resultingSelection) {
|
|
1031
|
+
const edits = changes.map((change) => {
|
|
1032
|
+
const rangeStart = this.getPositionAt(change.oldPosition);
|
|
1033
|
+
const rangeEnd = this.getPositionAt(change.oldEnd);
|
|
1034
|
+
return {
|
|
1035
|
+
range: new Range(rangeStart.lineNumber, rangeStart.column, rangeEnd.lineNumber, rangeEnd.column),
|
|
1036
|
+
text: change.newText
|
|
1037
|
+
};
|
|
1038
|
+
});
|
|
1039
|
+
this._applyUndoRedoEdits(edits, eol, false, true, resultingAlternativeVersionId, resultingSelection);
|
|
1040
|
+
}
|
|
1041
|
+
_applyUndoRedoEdits(edits, eol, isUndoing, isRedoing, resultingAlternativeVersionId, resultingSelection) {
|
|
1042
|
+
try {
|
|
1043
|
+
this._onDidChangeDecorations.beginDeferredEmit();
|
|
1044
|
+
this._eventEmitter.beginDeferredEmit();
|
|
1045
|
+
this._isUndoing = isUndoing;
|
|
1046
|
+
this._isRedoing = isRedoing;
|
|
1047
|
+
this.applyEdits(edits, false);
|
|
1048
|
+
this.setEOL(eol);
|
|
1049
|
+
this._overwriteAlternativeVersionId(resultingAlternativeVersionId);
|
|
1050
|
+
}
|
|
1051
|
+
finally {
|
|
1052
|
+
this._isUndoing = false;
|
|
1053
|
+
this._isRedoing = false;
|
|
1054
|
+
this._eventEmitter.endDeferredEmit(resultingSelection);
|
|
1055
|
+
this._onDidChangeDecorations.endDeferredEmit();
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
applyEdits(rawOperations, computeUndoEdits, reason) {
|
|
1059
|
+
try {
|
|
1060
|
+
this._onDidChangeDecorations.beginDeferredEmit();
|
|
1061
|
+
this._eventEmitter.beginDeferredEmit();
|
|
1062
|
+
const operations = this._validateEditOperations(rawOperations);
|
|
1063
|
+
return this._doApplyEdits(operations, computeUndoEdits ?? false, reason ?? EditSources.applyEdits());
|
|
1064
|
+
}
|
|
1065
|
+
finally {
|
|
1066
|
+
this._eventEmitter.endDeferredEmit();
|
|
1067
|
+
this._onDidChangeDecorations.endDeferredEmit();
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
_doApplyEdits(rawOperations, computeUndoEdits, reason) {
|
|
1071
|
+
const oldLineCount = this._buffer.getLineCount();
|
|
1072
|
+
const result = this._buffer.applyEdits(rawOperations, this._options.trimAutoWhitespace, computeUndoEdits);
|
|
1073
|
+
const newLineCount = this._buffer.getLineCount();
|
|
1074
|
+
const contentChanges = result.changes;
|
|
1075
|
+
this._trimAutoWhitespaceLines = result.trimAutoWhitespaceLineNumbers;
|
|
1076
|
+
if (contentChanges.length !== 0) {
|
|
1077
|
+
// We do a first pass to update decorations
|
|
1078
|
+
// because we want to read decorations in the second pass
|
|
1079
|
+
// where we will emit content change events
|
|
1080
|
+
// and we want to read the final decorations
|
|
1081
|
+
for (let i = 0, len = contentChanges.length; i < len; i++) {
|
|
1082
|
+
const change = contentChanges[i];
|
|
1083
|
+
this._decorationsTree.acceptReplace(change.rangeOffset, change.rangeLength, change.text.length, change.forceMoveMarkers);
|
|
1084
|
+
}
|
|
1085
|
+
const rawContentChanges = [];
|
|
1086
|
+
this._increaseVersionId();
|
|
1087
|
+
let lineCount = oldLineCount;
|
|
1088
|
+
for (let i = 0, len = contentChanges.length; i < len; i++) {
|
|
1089
|
+
const change = contentChanges[i];
|
|
1090
|
+
const [eolCount] = countEOL(change.text);
|
|
1091
|
+
this._onDidChangeDecorations.fire();
|
|
1092
|
+
const startLineNumber = change.range.startLineNumber;
|
|
1093
|
+
const endLineNumber = change.range.endLineNumber;
|
|
1094
|
+
const deletingLinesCnt = endLineNumber - startLineNumber;
|
|
1095
|
+
const insertingLinesCnt = eolCount;
|
|
1096
|
+
const editingLinesCnt = Math.min(deletingLinesCnt, insertingLinesCnt);
|
|
1097
|
+
const changeLineCountDelta = (insertingLinesCnt - deletingLinesCnt);
|
|
1098
|
+
const currentEditStartLineNumber = newLineCount - lineCount - changeLineCountDelta + startLineNumber;
|
|
1099
|
+
const firstEditLineNumber = currentEditStartLineNumber;
|
|
1100
|
+
const lastInsertedLineNumber = currentEditStartLineNumber + insertingLinesCnt;
|
|
1101
|
+
const decorationsWithInjectedTextInEditedRange = this._decorationsTree.getInjectedTextInInterval(this, this.getOffsetAt(new Position(firstEditLineNumber, 1)), this.getOffsetAt(new Position(lastInsertedLineNumber, this.getLineMaxColumn(lastInsertedLineNumber))), 0);
|
|
1102
|
+
const injectedTextInEditedRange = LineInjectedText.fromDecorations(decorationsWithInjectedTextInEditedRange);
|
|
1103
|
+
const injectedTextInEditedRangeQueue = new ArrayQueue(injectedTextInEditedRange);
|
|
1104
|
+
for (let j = editingLinesCnt; j >= 0; j--) {
|
|
1105
|
+
const editLineNumber = startLineNumber + j;
|
|
1106
|
+
const currentEditLineNumber = currentEditStartLineNumber + j;
|
|
1107
|
+
injectedTextInEditedRangeQueue.takeFromEndWhile(r => r.lineNumber > currentEditLineNumber);
|
|
1108
|
+
const decorationsInCurrentLine = injectedTextInEditedRangeQueue.takeFromEndWhile(r => r.lineNumber === currentEditLineNumber);
|
|
1109
|
+
rawContentChanges.push(new ModelRawLineChanged(editLineNumber, this.getLineContent(currentEditLineNumber), decorationsInCurrentLine));
|
|
1110
|
+
}
|
|
1111
|
+
if (editingLinesCnt < deletingLinesCnt) {
|
|
1112
|
+
// Must delete some lines
|
|
1113
|
+
const spliceStartLineNumber = startLineNumber + editingLinesCnt;
|
|
1114
|
+
rawContentChanges.push(new ModelRawLinesDeleted(spliceStartLineNumber + 1, endLineNumber));
|
|
1115
|
+
}
|
|
1116
|
+
if (editingLinesCnt < insertingLinesCnt) {
|
|
1117
|
+
const injectedTextInEditedRangeQueue = new ArrayQueue(injectedTextInEditedRange);
|
|
1118
|
+
// Must insert some lines
|
|
1119
|
+
const spliceLineNumber = startLineNumber + editingLinesCnt;
|
|
1120
|
+
const cnt = insertingLinesCnt - editingLinesCnt;
|
|
1121
|
+
const fromLineNumber = newLineCount - lineCount - cnt + spliceLineNumber + 1;
|
|
1122
|
+
const injectedTexts = [];
|
|
1123
|
+
const newLines = [];
|
|
1124
|
+
for (let i = 0; i < cnt; i++) {
|
|
1125
|
+
const lineNumber = fromLineNumber + i;
|
|
1126
|
+
newLines[i] = this.getLineContent(lineNumber);
|
|
1127
|
+
injectedTextInEditedRangeQueue.takeWhile(r => r.lineNumber < lineNumber);
|
|
1128
|
+
injectedTexts[i] = injectedTextInEditedRangeQueue.takeWhile(r => r.lineNumber === lineNumber);
|
|
1129
|
+
}
|
|
1130
|
+
rawContentChanges.push(new ModelRawLinesInserted(spliceLineNumber + 1, startLineNumber + insertingLinesCnt, newLines, injectedTexts));
|
|
1131
|
+
}
|
|
1132
|
+
lineCount += changeLineCountDelta;
|
|
1133
|
+
}
|
|
1134
|
+
this._emitContentChangedEvent(new ModelRawContentChangedEvent(rawContentChanges, this.getVersionId(), this._isUndoing, this._isRedoing), {
|
|
1135
|
+
changes: contentChanges,
|
|
1136
|
+
eol: this._buffer.getEOL(),
|
|
1137
|
+
isEolChange: false,
|
|
1138
|
+
versionId: this.getVersionId(),
|
|
1139
|
+
isUndoing: this._isUndoing,
|
|
1140
|
+
isRedoing: this._isRedoing,
|
|
1141
|
+
isFlush: false,
|
|
1142
|
+
detailedReasons: [reason],
|
|
1143
|
+
detailedReasonsChangeLengths: [contentChanges.length],
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
return (result.reverseEdits === null ? undefined : result.reverseEdits);
|
|
1147
|
+
}
|
|
1148
|
+
undo() {
|
|
1149
|
+
return this._undoRedoService.undo(this.uri);
|
|
1150
|
+
}
|
|
1151
|
+
canUndo() {
|
|
1152
|
+
return this._undoRedoService.canUndo(this.uri);
|
|
1153
|
+
}
|
|
1154
|
+
redo() {
|
|
1155
|
+
return this._undoRedoService.redo(this.uri);
|
|
1156
|
+
}
|
|
1157
|
+
canRedo() {
|
|
1158
|
+
return this._undoRedoService.canRedo(this.uri);
|
|
1159
|
+
}
|
|
1160
|
+
//#endregion
|
|
1161
|
+
//#region Decorations
|
|
1162
|
+
handleBeforeFireDecorationsChangedEvent(affectedInjectedTextLines, affectedLineHeights, affectedFontLines) {
|
|
1163
|
+
// This is called before the decoration changed event is fired.
|
|
1164
|
+
if (affectedInjectedTextLines && affectedInjectedTextLines.size > 0) {
|
|
1165
|
+
const affectedLines = Array.from(affectedInjectedTextLines);
|
|
1166
|
+
const lineChangeEvents = affectedLines.map(lineNumber => new ModelRawLineChanged(lineNumber, this.getLineContent(lineNumber), this._getInjectedTextInLine(lineNumber)));
|
|
1167
|
+
this._onDidChangeInjectedText.fire(new ModelInjectedTextChangedEvent(lineChangeEvents));
|
|
1168
|
+
}
|
|
1169
|
+
if (affectedLineHeights && affectedLineHeights.size > 0) {
|
|
1170
|
+
const affectedLines = Array.from(affectedLineHeights);
|
|
1171
|
+
const lineHeightChangeEvent = affectedLines.map(specialLineHeightChange => new ModelLineHeightChanged(specialLineHeightChange.ownerId, specialLineHeightChange.decorationId, specialLineHeightChange.lineNumber, specialLineHeightChange.lineHeight));
|
|
1172
|
+
this._onDidChangeLineHeight.fire(new ModelLineHeightChangedEvent(lineHeightChangeEvent));
|
|
1173
|
+
}
|
|
1174
|
+
if (affectedFontLines && affectedFontLines.size > 0) {
|
|
1175
|
+
const affectedLines = Array.from(affectedFontLines);
|
|
1176
|
+
const fontChangeEvent = affectedLines.map(fontChange => new ModelFontChanged(fontChange.ownerId, fontChange.lineNumber));
|
|
1177
|
+
this._onDidChangeFont.fire(new ModelFontChangedEvent(fontChangeEvent));
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
changeDecorations(callback, ownerId = 0) {
|
|
1181
|
+
this._assertNotDisposed();
|
|
1182
|
+
try {
|
|
1183
|
+
this._onDidChangeDecorations.beginDeferredEmit();
|
|
1184
|
+
return this._changeDecorations(ownerId, callback);
|
|
1185
|
+
}
|
|
1186
|
+
finally {
|
|
1187
|
+
this._onDidChangeDecorations.endDeferredEmit();
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
_changeDecorations(ownerId, callback) {
|
|
1191
|
+
const changeAccessor = {
|
|
1192
|
+
addDecoration: (range, options) => {
|
|
1193
|
+
return this._deltaDecorationsImpl(ownerId, [], [{ range: range, options: options }])[0];
|
|
1194
|
+
},
|
|
1195
|
+
changeDecoration: (id, newRange) => {
|
|
1196
|
+
this._changeDecorationImpl(ownerId, id, newRange);
|
|
1197
|
+
},
|
|
1198
|
+
changeDecorationOptions: (id, options) => {
|
|
1199
|
+
this._changeDecorationOptionsImpl(ownerId, id, _normalizeOptions(options));
|
|
1200
|
+
},
|
|
1201
|
+
removeDecoration: (id) => {
|
|
1202
|
+
this._deltaDecorationsImpl(ownerId, [id], []);
|
|
1203
|
+
},
|
|
1204
|
+
deltaDecorations: (oldDecorations, newDecorations) => {
|
|
1205
|
+
if (oldDecorations.length === 0 && newDecorations.length === 0) {
|
|
1206
|
+
// nothing to do
|
|
1207
|
+
return [];
|
|
1208
|
+
}
|
|
1209
|
+
return this._deltaDecorationsImpl(ownerId, oldDecorations, newDecorations);
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
let result = null;
|
|
1213
|
+
try {
|
|
1214
|
+
result = callback(changeAccessor);
|
|
1215
|
+
}
|
|
1216
|
+
catch (e) {
|
|
1217
|
+
onUnexpectedError(e);
|
|
1218
|
+
}
|
|
1219
|
+
// Invalidate change accessor
|
|
1220
|
+
changeAccessor.addDecoration = invalidFunc;
|
|
1221
|
+
changeAccessor.changeDecoration = invalidFunc;
|
|
1222
|
+
changeAccessor.changeDecorationOptions = invalidFunc;
|
|
1223
|
+
changeAccessor.removeDecoration = invalidFunc;
|
|
1224
|
+
changeAccessor.deltaDecorations = invalidFunc;
|
|
1225
|
+
return result;
|
|
1226
|
+
}
|
|
1227
|
+
deltaDecorations(oldDecorations, newDecorations, ownerId = 0) {
|
|
1228
|
+
this._assertNotDisposed();
|
|
1229
|
+
if (!oldDecorations) {
|
|
1230
|
+
oldDecorations = [];
|
|
1231
|
+
}
|
|
1232
|
+
if (oldDecorations.length === 0 && newDecorations.length === 0) {
|
|
1233
|
+
// nothing to do
|
|
1234
|
+
return [];
|
|
1235
|
+
}
|
|
1236
|
+
try {
|
|
1237
|
+
this._deltaDecorationCallCnt++;
|
|
1238
|
+
if (this._deltaDecorationCallCnt > 1) {
|
|
1239
|
+
console.warn(`Invoking deltaDecorations recursively could lead to leaking decorations.`);
|
|
1240
|
+
onUnexpectedError(new Error(`Invoking deltaDecorations recursively could lead to leaking decorations.`));
|
|
1241
|
+
}
|
|
1242
|
+
this._onDidChangeDecorations.beginDeferredEmit();
|
|
1243
|
+
return this._deltaDecorationsImpl(ownerId, oldDecorations, newDecorations);
|
|
1244
|
+
}
|
|
1245
|
+
finally {
|
|
1246
|
+
this._onDidChangeDecorations.endDeferredEmit();
|
|
1247
|
+
this._deltaDecorationCallCnt--;
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
_getTrackedRange(id) {
|
|
1251
|
+
return this.getDecorationRange(id);
|
|
1252
|
+
}
|
|
1253
|
+
_setTrackedRange(id, newRange, newStickiness) {
|
|
1254
|
+
const node = (id ? this._decorations[id] : null);
|
|
1255
|
+
if (!node) {
|
|
1256
|
+
if (!newRange) {
|
|
1257
|
+
// node doesn't exist, the request is to delete => nothing to do
|
|
1258
|
+
return null;
|
|
1259
|
+
}
|
|
1260
|
+
// node doesn't exist, the request is to set => add the tracked range
|
|
1261
|
+
return this._deltaDecorationsImpl(0, [], [{ range: newRange, options: TRACKED_RANGE_OPTIONS[newStickiness] }], true)[0];
|
|
1262
|
+
}
|
|
1263
|
+
if (!newRange) {
|
|
1264
|
+
// node exists, the request is to delete => delete node
|
|
1265
|
+
this._decorationsTree.delete(node);
|
|
1266
|
+
delete this._decorations[node.id];
|
|
1267
|
+
return null;
|
|
1268
|
+
}
|
|
1269
|
+
// node exists, the request is to set => change the tracked range and its options
|
|
1270
|
+
const range = this._validateRangeRelaxedNoAllocations(newRange);
|
|
1271
|
+
const startOffset = this._buffer.getOffsetAt(range.startLineNumber, range.startColumn);
|
|
1272
|
+
const endOffset = this._buffer.getOffsetAt(range.endLineNumber, range.endColumn);
|
|
1273
|
+
this._decorationsTree.delete(node);
|
|
1274
|
+
node.reset(this.getVersionId(), startOffset, endOffset, range);
|
|
1275
|
+
node.setOptions(TRACKED_RANGE_OPTIONS[newStickiness]);
|
|
1276
|
+
this._decorationsTree.insert(node);
|
|
1277
|
+
return node.id;
|
|
1278
|
+
}
|
|
1279
|
+
removeAllDecorationsWithOwnerId(ownerId) {
|
|
1280
|
+
if (this._isDisposed) {
|
|
1281
|
+
return;
|
|
1282
|
+
}
|
|
1283
|
+
const nodes = this._decorationsTree.collectNodesFromOwner(ownerId);
|
|
1284
|
+
for (let i = 0, len = nodes.length; i < len; i++) {
|
|
1285
|
+
const node = nodes[i];
|
|
1286
|
+
this._decorationsTree.delete(node);
|
|
1287
|
+
delete this._decorations[node.id];
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
getDecorationOptions(decorationId) {
|
|
1291
|
+
const node = this._decorations[decorationId];
|
|
1292
|
+
if (!node) {
|
|
1293
|
+
return null;
|
|
1294
|
+
}
|
|
1295
|
+
return node.options;
|
|
1296
|
+
}
|
|
1297
|
+
getDecorationRange(decorationId) {
|
|
1298
|
+
const node = this._decorations[decorationId];
|
|
1299
|
+
if (!node) {
|
|
1300
|
+
return null;
|
|
1301
|
+
}
|
|
1302
|
+
return this._decorationsTree.getNodeRange(this, node);
|
|
1303
|
+
}
|
|
1304
|
+
getLineDecorations(lineNumber, ownerId = 0, filterOutValidation = false, filterFontDecorations = false) {
|
|
1305
|
+
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
|
|
1306
|
+
return [];
|
|
1307
|
+
}
|
|
1308
|
+
return this.getLinesDecorations(lineNumber, lineNumber, ownerId, filterOutValidation, filterFontDecorations);
|
|
1309
|
+
}
|
|
1310
|
+
getLinesDecorations(_startLineNumber, _endLineNumber, ownerId = 0, filterOutValidation = false, filterFontDecorations = false, onlyMarginDecorations = false) {
|
|
1311
|
+
const lineCount = this.getLineCount();
|
|
1312
|
+
const startLineNumber = Math.min(lineCount, Math.max(1, _startLineNumber));
|
|
1313
|
+
const endLineNumber = Math.min(lineCount, Math.max(1, _endLineNumber));
|
|
1314
|
+
const endColumn = this.getLineMaxColumn(endLineNumber);
|
|
1315
|
+
const range = new Range(startLineNumber, 1, endLineNumber, endColumn);
|
|
1316
|
+
const decorations = this._getDecorationsInRange(range, ownerId, filterOutValidation, filterFontDecorations, onlyMarginDecorations);
|
|
1317
|
+
pushMany(decorations, this._decorationProvider.getDecorationsInRange(range, ownerId, filterOutValidation));
|
|
1318
|
+
return decorations;
|
|
1319
|
+
}
|
|
1320
|
+
getDecorationsInRange(range, ownerId = 0, filterOutValidation = false, filterFontDecorations = false, onlyMinimapDecorations = false, onlyMarginDecorations = false) {
|
|
1321
|
+
const validatedRange = this.validateRange(range);
|
|
1322
|
+
const decorations = this._getDecorationsInRange(validatedRange, ownerId, filterOutValidation, filterFontDecorations, onlyMarginDecorations);
|
|
1323
|
+
pushMany(decorations, this._decorationProvider.getDecorationsInRange(validatedRange, ownerId, filterOutValidation, onlyMinimapDecorations));
|
|
1324
|
+
return decorations;
|
|
1325
|
+
}
|
|
1326
|
+
getOverviewRulerDecorations(ownerId = 0, filterOutValidation = false, filterFontDecorations = false) {
|
|
1327
|
+
return this._decorationsTree.getAll(this, ownerId, filterOutValidation, filterFontDecorations, true, false);
|
|
1328
|
+
}
|
|
1329
|
+
getInjectedTextDecorations(ownerId = 0) {
|
|
1330
|
+
return this._decorationsTree.getAllInjectedText(this, ownerId);
|
|
1331
|
+
}
|
|
1332
|
+
getCustomLineHeightsDecorations(ownerId = 0) {
|
|
1333
|
+
return this._decorationsTree.getAllCustomLineHeights(this, ownerId);
|
|
1334
|
+
}
|
|
1335
|
+
_getInjectedTextInLine(lineNumber) {
|
|
1336
|
+
const startOffset = this._buffer.getOffsetAt(lineNumber, 1);
|
|
1337
|
+
const endOffset = startOffset + this._buffer.getLineLength(lineNumber);
|
|
1338
|
+
const result = this._decorationsTree.getInjectedTextInInterval(this, startOffset, endOffset, 0);
|
|
1339
|
+
return LineInjectedText.fromDecorations(result).filter(t => t.lineNumber === lineNumber);
|
|
1340
|
+
}
|
|
1341
|
+
getFontDecorationsInRange(range, ownerId = 0) {
|
|
1342
|
+
const startOffset = this._buffer.getOffsetAt(range.startLineNumber, range.startColumn);
|
|
1343
|
+
const endOffset = this._buffer.getOffsetAt(range.endLineNumber, range.endColumn);
|
|
1344
|
+
return this._decorationsTree.getFontDecorationsInInterval(this, startOffset, endOffset, ownerId);
|
|
1345
|
+
}
|
|
1346
|
+
getAllDecorations(ownerId = 0, filterOutValidation = false, filterFontDecorations = false) {
|
|
1347
|
+
let result = this._decorationsTree.getAll(this, ownerId, filterOutValidation, filterFontDecorations, false, false);
|
|
1348
|
+
result = result.concat(this._decorationProvider.getAllDecorations(ownerId, filterOutValidation));
|
|
1349
|
+
return result;
|
|
1350
|
+
}
|
|
1351
|
+
getAllMarginDecorations(ownerId = 0) {
|
|
1352
|
+
return this._decorationsTree.getAll(this, ownerId, false, false, false, true);
|
|
1353
|
+
}
|
|
1354
|
+
_getDecorationsInRange(filterRange, filterOwnerId, filterOutValidation, filterFontDecorations, onlyMarginDecorations) {
|
|
1355
|
+
const startOffset = this._buffer.getOffsetAt(filterRange.startLineNumber, filterRange.startColumn);
|
|
1356
|
+
const endOffset = this._buffer.getOffsetAt(filterRange.endLineNumber, filterRange.endColumn);
|
|
1357
|
+
return this._decorationsTree.getAllInInterval(this, startOffset, endOffset, filterOwnerId, filterOutValidation, filterFontDecorations, onlyMarginDecorations);
|
|
1358
|
+
}
|
|
1359
|
+
getRangeAt(start, end) {
|
|
1360
|
+
return this._buffer.getRangeAt(start, end - start);
|
|
1361
|
+
}
|
|
1362
|
+
_changeDecorationImpl(ownerId, decorationId, _range) {
|
|
1363
|
+
const node = this._decorations[decorationId];
|
|
1364
|
+
if (!node) {
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
if (node.options.after) {
|
|
1368
|
+
const oldRange = this.getDecorationRange(decorationId);
|
|
1369
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(oldRange.endLineNumber);
|
|
1370
|
+
}
|
|
1371
|
+
if (node.options.before) {
|
|
1372
|
+
const oldRange = this.getDecorationRange(decorationId);
|
|
1373
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(oldRange.startLineNumber);
|
|
1374
|
+
}
|
|
1375
|
+
if (node.options.lineHeight !== null) {
|
|
1376
|
+
const oldRange = this.getDecorationRange(decorationId);
|
|
1377
|
+
this._onDidChangeDecorations.recordLineAffectedByLineHeightChange(ownerId, decorationId, oldRange.startLineNumber, null);
|
|
1378
|
+
}
|
|
1379
|
+
if (node.options.affectsFont) {
|
|
1380
|
+
const oldRange = this.getDecorationRange(decorationId);
|
|
1381
|
+
this._onDidChangeDecorations.recordLineAffectedByFontChange(ownerId, node.id, oldRange.startLineNumber);
|
|
1382
|
+
}
|
|
1383
|
+
const range = this._validateRangeRelaxedNoAllocations(_range);
|
|
1384
|
+
const startOffset = this._buffer.getOffsetAt(range.startLineNumber, range.startColumn);
|
|
1385
|
+
const endOffset = this._buffer.getOffsetAt(range.endLineNumber, range.endColumn);
|
|
1386
|
+
this._decorationsTree.delete(node);
|
|
1387
|
+
node.reset(this.getVersionId(), startOffset, endOffset, range);
|
|
1388
|
+
this._decorationsTree.insert(node);
|
|
1389
|
+
this._onDidChangeDecorations.checkAffectedAndFire(node.options);
|
|
1390
|
+
if (node.options.after) {
|
|
1391
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(range.endLineNumber);
|
|
1392
|
+
}
|
|
1393
|
+
if (node.options.before) {
|
|
1394
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(range.startLineNumber);
|
|
1395
|
+
}
|
|
1396
|
+
if (node.options.lineHeight !== null) {
|
|
1397
|
+
this._onDidChangeDecorations.recordLineAffectedByLineHeightChange(ownerId, decorationId, range.startLineNumber, node.options.lineHeight);
|
|
1398
|
+
}
|
|
1399
|
+
if (node.options.affectsFont) {
|
|
1400
|
+
this._onDidChangeDecorations.recordLineAffectedByFontChange(ownerId, node.id, range.startLineNumber);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
_changeDecorationOptionsImpl(ownerId, decorationId, options) {
|
|
1404
|
+
const node = this._decorations[decorationId];
|
|
1405
|
+
if (!node) {
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1408
|
+
const nodeWasInOverviewRuler = (node.options.overviewRuler && node.options.overviewRuler.color ? true : false);
|
|
1409
|
+
const nodeIsInOverviewRuler = (options.overviewRuler && options.overviewRuler.color ? true : false);
|
|
1410
|
+
this._onDidChangeDecorations.checkAffectedAndFire(node.options);
|
|
1411
|
+
this._onDidChangeDecorations.checkAffectedAndFire(options);
|
|
1412
|
+
if (node.options.after || options.after) {
|
|
1413
|
+
const nodeRange = this._decorationsTree.getNodeRange(this, node);
|
|
1414
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(nodeRange.endLineNumber);
|
|
1415
|
+
}
|
|
1416
|
+
if (node.options.before || options.before) {
|
|
1417
|
+
const nodeRange = this._decorationsTree.getNodeRange(this, node);
|
|
1418
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(nodeRange.startLineNumber);
|
|
1419
|
+
}
|
|
1420
|
+
if (node.options.lineHeight !== null || options.lineHeight !== null) {
|
|
1421
|
+
const nodeRange = this._decorationsTree.getNodeRange(this, node);
|
|
1422
|
+
this._onDidChangeDecorations.recordLineAffectedByLineHeightChange(ownerId, decorationId, nodeRange.startLineNumber, options.lineHeight);
|
|
1423
|
+
}
|
|
1424
|
+
if (node.options.affectsFont || options.affectsFont) {
|
|
1425
|
+
const nodeRange = this._decorationsTree.getNodeRange(this, node);
|
|
1426
|
+
this._onDidChangeDecorations.recordLineAffectedByFontChange(ownerId, decorationId, nodeRange.startLineNumber);
|
|
1427
|
+
}
|
|
1428
|
+
const movedInOverviewRuler = nodeWasInOverviewRuler !== nodeIsInOverviewRuler;
|
|
1429
|
+
const changedWhetherInjectedText = isOptionsInjectedText(options) !== isNodeInjectedText(node);
|
|
1430
|
+
if (movedInOverviewRuler || changedWhetherInjectedText) {
|
|
1431
|
+
this._decorationsTree.delete(node);
|
|
1432
|
+
node.setOptions(options);
|
|
1433
|
+
this._decorationsTree.insert(node);
|
|
1434
|
+
}
|
|
1435
|
+
else {
|
|
1436
|
+
node.setOptions(options);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
_deltaDecorationsImpl(ownerId, oldDecorationsIds, newDecorations, suppressEvents = false) {
|
|
1440
|
+
const versionId = this.getVersionId();
|
|
1441
|
+
const oldDecorationsLen = oldDecorationsIds.length;
|
|
1442
|
+
let oldDecorationIndex = 0;
|
|
1443
|
+
const newDecorationsLen = newDecorations.length;
|
|
1444
|
+
let newDecorationIndex = 0;
|
|
1445
|
+
this._onDidChangeDecorations.beginDeferredEmit();
|
|
1446
|
+
try {
|
|
1447
|
+
const result = new Array(newDecorationsLen);
|
|
1448
|
+
while (oldDecorationIndex < oldDecorationsLen || newDecorationIndex < newDecorationsLen) {
|
|
1449
|
+
let node = null;
|
|
1450
|
+
if (oldDecorationIndex < oldDecorationsLen) {
|
|
1451
|
+
// (1) get ourselves an old node
|
|
1452
|
+
let decorationId;
|
|
1453
|
+
do {
|
|
1454
|
+
decorationId = oldDecorationsIds[oldDecorationIndex++];
|
|
1455
|
+
node = this._decorations[decorationId];
|
|
1456
|
+
} while (!node && oldDecorationIndex < oldDecorationsLen);
|
|
1457
|
+
// (2) remove the node from the tree (if it exists)
|
|
1458
|
+
if (node) {
|
|
1459
|
+
if (node.options.after) {
|
|
1460
|
+
const nodeRange = this._decorationsTree.getNodeRange(this, node);
|
|
1461
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(nodeRange.endLineNumber);
|
|
1462
|
+
}
|
|
1463
|
+
if (node.options.before) {
|
|
1464
|
+
const nodeRange = this._decorationsTree.getNodeRange(this, node);
|
|
1465
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(nodeRange.startLineNumber);
|
|
1466
|
+
}
|
|
1467
|
+
if (node.options.lineHeight !== null) {
|
|
1468
|
+
const nodeRange = this._decorationsTree.getNodeRange(this, node);
|
|
1469
|
+
this._onDidChangeDecorations.recordLineAffectedByLineHeightChange(ownerId, decorationId, nodeRange.startLineNumber, null);
|
|
1470
|
+
}
|
|
1471
|
+
if (node.options.affectsFont) {
|
|
1472
|
+
const nodeRange = this._decorationsTree.getNodeRange(this, node);
|
|
1473
|
+
this._onDidChangeDecorations.recordLineAffectedByFontChange(ownerId, decorationId, nodeRange.startLineNumber);
|
|
1474
|
+
}
|
|
1475
|
+
this._decorationsTree.delete(node);
|
|
1476
|
+
if (!suppressEvents) {
|
|
1477
|
+
this._onDidChangeDecorations.checkAffectedAndFire(node.options);
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
if (newDecorationIndex < newDecorationsLen) {
|
|
1482
|
+
// (3) create a new node if necessary
|
|
1483
|
+
if (!node) {
|
|
1484
|
+
const internalDecorationId = (++this._lastDecorationId);
|
|
1485
|
+
const decorationId = `${this._instanceId};${internalDecorationId}`;
|
|
1486
|
+
node = new IntervalNode(decorationId, 0, 0);
|
|
1487
|
+
this._decorations[decorationId] = node;
|
|
1488
|
+
}
|
|
1489
|
+
// (4) initialize node
|
|
1490
|
+
const newDecoration = newDecorations[newDecorationIndex];
|
|
1491
|
+
const range = this._validateRangeRelaxedNoAllocations(newDecoration.range);
|
|
1492
|
+
const options = _normalizeOptions(newDecoration.options);
|
|
1493
|
+
const startOffset = this._buffer.getOffsetAt(range.startLineNumber, range.startColumn);
|
|
1494
|
+
const endOffset = this._buffer.getOffsetAt(range.endLineNumber, range.endColumn);
|
|
1495
|
+
node.ownerId = ownerId;
|
|
1496
|
+
node.reset(versionId, startOffset, endOffset, range);
|
|
1497
|
+
node.setOptions(options);
|
|
1498
|
+
if (node.options.after) {
|
|
1499
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(range.endLineNumber);
|
|
1500
|
+
}
|
|
1501
|
+
if (node.options.before) {
|
|
1502
|
+
this._onDidChangeDecorations.recordLineAffectedByInjectedText(range.startLineNumber);
|
|
1503
|
+
}
|
|
1504
|
+
if (node.options.lineHeight !== null) {
|
|
1505
|
+
this._onDidChangeDecorations.recordLineAffectedByLineHeightChange(ownerId, node.id, range.startLineNumber, node.options.lineHeight);
|
|
1506
|
+
}
|
|
1507
|
+
if (node.options.affectsFont) {
|
|
1508
|
+
this._onDidChangeDecorations.recordLineAffectedByFontChange(ownerId, node.id, range.startLineNumber);
|
|
1509
|
+
}
|
|
1510
|
+
if (!suppressEvents) {
|
|
1511
|
+
this._onDidChangeDecorations.checkAffectedAndFire(options);
|
|
1512
|
+
}
|
|
1513
|
+
this._decorationsTree.insert(node);
|
|
1514
|
+
result[newDecorationIndex] = node.id;
|
|
1515
|
+
newDecorationIndex++;
|
|
1516
|
+
}
|
|
1517
|
+
else {
|
|
1518
|
+
if (node) {
|
|
1519
|
+
delete this._decorations[node.id];
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
return result;
|
|
1524
|
+
}
|
|
1525
|
+
finally {
|
|
1526
|
+
this._onDidChangeDecorations.endDeferredEmit();
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
//#endregion
|
|
1530
|
+
//#region Tokenization
|
|
1531
|
+
// TODO move them to the tokenization part.
|
|
1532
|
+
getLanguageId() {
|
|
1533
|
+
return this.tokenization.getLanguageId();
|
|
1534
|
+
}
|
|
1535
|
+
setLanguage(languageIdOrSelection, source) {
|
|
1536
|
+
if (typeof languageIdOrSelection === 'string') {
|
|
1537
|
+
this._languageSelectionListener.clear();
|
|
1538
|
+
this._setLanguage(languageIdOrSelection, source);
|
|
1539
|
+
}
|
|
1540
|
+
else {
|
|
1541
|
+
this._languageSelectionListener.value = languageIdOrSelection.onDidChange(() => this._setLanguage(languageIdOrSelection.languageId, source));
|
|
1542
|
+
this._setLanguage(languageIdOrSelection.languageId, source);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
_setLanguage(languageId, source) {
|
|
1546
|
+
this.tokenization.setLanguageId(languageId, source);
|
|
1547
|
+
this._languageService.requestRichLanguageFeatures(languageId);
|
|
1548
|
+
}
|
|
1549
|
+
getLanguageIdAtPosition(lineNumber, column) {
|
|
1550
|
+
return this.tokenization.getLanguageIdAtPosition(lineNumber, column);
|
|
1551
|
+
}
|
|
1552
|
+
getWordAtPosition(position) {
|
|
1553
|
+
return this._tokenizationTextModelPart.getWordAtPosition(position);
|
|
1554
|
+
}
|
|
1555
|
+
getWordUntilPosition(position) {
|
|
1556
|
+
return this._tokenizationTextModelPart.getWordUntilPosition(position);
|
|
1557
|
+
}
|
|
1558
|
+
//#endregion
|
|
1559
|
+
normalizePosition(position, affinity) {
|
|
1560
|
+
return position;
|
|
1561
|
+
}
|
|
1562
|
+
/**
|
|
1563
|
+
* Gets the column at which indentation stops at a given line.
|
|
1564
|
+
* @internal
|
|
1565
|
+
*/
|
|
1566
|
+
getLineIndentColumn(lineNumber) {
|
|
1567
|
+
// Columns start with 1.
|
|
1568
|
+
return indentOfLine(this.getLineContent(lineNumber)) + 1;
|
|
1569
|
+
}
|
|
1570
|
+
toString() {
|
|
1571
|
+
return `TextModel(${this.uri.toString()})`;
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
TextModel = TextModel_1 = __decorate([
|
|
1575
|
+
__param(4, IUndoRedoService),
|
|
1576
|
+
__param(5, ILanguageService),
|
|
1577
|
+
__param(6, ILanguageConfigurationService),
|
|
1578
|
+
__param(7, IInstantiationService)
|
|
1579
|
+
], TextModel);
|
|
1580
|
+
function indentOfLine(line) {
|
|
1581
|
+
let indent = 0;
|
|
1582
|
+
for (const c of line) {
|
|
1583
|
+
if (c === ' ' || c === '\t') {
|
|
1584
|
+
indent++;
|
|
1585
|
+
}
|
|
1586
|
+
else {
|
|
1587
|
+
break;
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
return indent;
|
|
1591
|
+
}
|
|
1592
|
+
//#region Decorations
|
|
1593
|
+
function isNodeInOverviewRuler(node) {
|
|
1594
|
+
return (node.options.overviewRuler && node.options.overviewRuler.color ? true : false);
|
|
1595
|
+
}
|
|
1596
|
+
function isOptionsInjectedText(options) {
|
|
1597
|
+
return !!options.after || !!options.before;
|
|
1598
|
+
}
|
|
1599
|
+
function isNodeInjectedText(node) {
|
|
1600
|
+
return !!node.options.after || !!node.options.before;
|
|
1601
|
+
}
|
|
1602
|
+
class DecorationsTrees {
|
|
1603
|
+
constructor() {
|
|
1604
|
+
this._decorationsTree0 = new IntervalTree();
|
|
1605
|
+
this._decorationsTree1 = new IntervalTree();
|
|
1606
|
+
this._injectedTextDecorationsTree = new IntervalTree();
|
|
1607
|
+
}
|
|
1608
|
+
ensureAllNodesHaveRanges(host) {
|
|
1609
|
+
this.getAll(host, 0, false, false, false, false);
|
|
1610
|
+
}
|
|
1611
|
+
_ensureNodesHaveRanges(host, nodes) {
|
|
1612
|
+
for (const node of nodes) {
|
|
1613
|
+
if (node.range === null) {
|
|
1614
|
+
node.range = host.getRangeAt(node.cachedAbsoluteStart, node.cachedAbsoluteEnd);
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
return nodes;
|
|
1618
|
+
}
|
|
1619
|
+
getAllInInterval(host, start, end, filterOwnerId, filterOutValidation, filterFontDecorations, onlyMarginDecorations) {
|
|
1620
|
+
const versionId = host.getVersionId();
|
|
1621
|
+
const result = this._intervalSearch(start, end, filterOwnerId, filterOutValidation, filterFontDecorations, versionId, onlyMarginDecorations);
|
|
1622
|
+
return this._ensureNodesHaveRanges(host, result);
|
|
1623
|
+
}
|
|
1624
|
+
_intervalSearch(start, end, filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations) {
|
|
1625
|
+
const r0 = this._decorationsTree0.intervalSearch(start, end, filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations);
|
|
1626
|
+
const r1 = this._decorationsTree1.intervalSearch(start, end, filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations);
|
|
1627
|
+
const r2 = this._injectedTextDecorationsTree.intervalSearch(start, end, filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations);
|
|
1628
|
+
return r0.concat(r1).concat(r2);
|
|
1629
|
+
}
|
|
1630
|
+
getInjectedTextInInterval(host, start, end, filterOwnerId) {
|
|
1631
|
+
const versionId = host.getVersionId();
|
|
1632
|
+
const result = this._injectedTextDecorationsTree.intervalSearch(start, end, filterOwnerId, false, false, versionId, false);
|
|
1633
|
+
return this._ensureNodesHaveRanges(host, result).filter((i) => i.options.showIfCollapsed || !i.range.isEmpty());
|
|
1634
|
+
}
|
|
1635
|
+
getFontDecorationsInInterval(host, start, end, filterOwnerId) {
|
|
1636
|
+
const versionId = host.getVersionId();
|
|
1637
|
+
const decorations = this._decorationsTree0.intervalSearch(start, end, filterOwnerId, false, false, versionId, false);
|
|
1638
|
+
return this._ensureNodesHaveRanges(host, decorations).filter((i) => i.options.affectsFont);
|
|
1639
|
+
}
|
|
1640
|
+
getAllInjectedText(host, filterOwnerId) {
|
|
1641
|
+
const versionId = host.getVersionId();
|
|
1642
|
+
const result = this._injectedTextDecorationsTree.search(filterOwnerId, false, false, versionId, false);
|
|
1643
|
+
return this._ensureNodesHaveRanges(host, result).filter((i) => i.options.showIfCollapsed || !i.range.isEmpty());
|
|
1644
|
+
}
|
|
1645
|
+
getAllCustomLineHeights(host, filterOwnerId) {
|
|
1646
|
+
const versionId = host.getVersionId();
|
|
1647
|
+
const result = this._search(filterOwnerId, false, false, false, versionId, false);
|
|
1648
|
+
return this._ensureNodesHaveRanges(host, result).filter((i) => typeof i.options.lineHeight === 'number');
|
|
1649
|
+
}
|
|
1650
|
+
getAll(host, filterOwnerId, filterOutValidation, filterFontDecorations, overviewRulerOnly, onlyMarginDecorations) {
|
|
1651
|
+
const versionId = host.getVersionId();
|
|
1652
|
+
const result = this._search(filterOwnerId, filterOutValidation, filterFontDecorations, overviewRulerOnly, versionId, onlyMarginDecorations);
|
|
1653
|
+
return this._ensureNodesHaveRanges(host, result);
|
|
1654
|
+
}
|
|
1655
|
+
_search(filterOwnerId, filterOutValidation, filterFontDecorations, overviewRulerOnly, cachedVersionId, onlyMarginDecorations) {
|
|
1656
|
+
if (overviewRulerOnly) {
|
|
1657
|
+
return this._decorationsTree1.search(filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations);
|
|
1658
|
+
}
|
|
1659
|
+
else {
|
|
1660
|
+
const r0 = this._decorationsTree0.search(filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations);
|
|
1661
|
+
const r1 = this._decorationsTree1.search(filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations);
|
|
1662
|
+
const r2 = this._injectedTextDecorationsTree.search(filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations);
|
|
1663
|
+
return r0.concat(r1).concat(r2);
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
collectNodesFromOwner(ownerId) {
|
|
1667
|
+
const r0 = this._decorationsTree0.collectNodesFromOwner(ownerId);
|
|
1668
|
+
const r1 = this._decorationsTree1.collectNodesFromOwner(ownerId);
|
|
1669
|
+
const r2 = this._injectedTextDecorationsTree.collectNodesFromOwner(ownerId);
|
|
1670
|
+
return r0.concat(r1).concat(r2);
|
|
1671
|
+
}
|
|
1672
|
+
collectNodesPostOrder() {
|
|
1673
|
+
const r0 = this._decorationsTree0.collectNodesPostOrder();
|
|
1674
|
+
const r1 = this._decorationsTree1.collectNodesPostOrder();
|
|
1675
|
+
const r2 = this._injectedTextDecorationsTree.collectNodesPostOrder();
|
|
1676
|
+
return r0.concat(r1).concat(r2);
|
|
1677
|
+
}
|
|
1678
|
+
insert(node) {
|
|
1679
|
+
if (isNodeInjectedText(node)) {
|
|
1680
|
+
this._injectedTextDecorationsTree.insert(node);
|
|
1681
|
+
}
|
|
1682
|
+
else if (isNodeInOverviewRuler(node)) {
|
|
1683
|
+
this._decorationsTree1.insert(node);
|
|
1684
|
+
}
|
|
1685
|
+
else {
|
|
1686
|
+
this._decorationsTree0.insert(node);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
delete(node) {
|
|
1690
|
+
if (isNodeInjectedText(node)) {
|
|
1691
|
+
this._injectedTextDecorationsTree.delete(node);
|
|
1692
|
+
}
|
|
1693
|
+
else if (isNodeInOverviewRuler(node)) {
|
|
1694
|
+
this._decorationsTree1.delete(node);
|
|
1695
|
+
}
|
|
1696
|
+
else {
|
|
1697
|
+
this._decorationsTree0.delete(node);
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
getNodeRange(host, node) {
|
|
1701
|
+
const versionId = host.getVersionId();
|
|
1702
|
+
if (node.cachedVersionId !== versionId) {
|
|
1703
|
+
this._resolveNode(node, versionId);
|
|
1704
|
+
}
|
|
1705
|
+
if (node.range === null) {
|
|
1706
|
+
node.range = host.getRangeAt(node.cachedAbsoluteStart, node.cachedAbsoluteEnd);
|
|
1707
|
+
}
|
|
1708
|
+
return node.range;
|
|
1709
|
+
}
|
|
1710
|
+
_resolveNode(node, cachedVersionId) {
|
|
1711
|
+
if (isNodeInjectedText(node)) {
|
|
1712
|
+
this._injectedTextDecorationsTree.resolveNode(node, cachedVersionId);
|
|
1713
|
+
}
|
|
1714
|
+
else if (isNodeInOverviewRuler(node)) {
|
|
1715
|
+
this._decorationsTree1.resolveNode(node, cachedVersionId);
|
|
1716
|
+
}
|
|
1717
|
+
else {
|
|
1718
|
+
this._decorationsTree0.resolveNode(node, cachedVersionId);
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
acceptReplace(offset, length, textLength, forceMoveMarkers) {
|
|
1722
|
+
this._decorationsTree0.acceptReplace(offset, length, textLength, forceMoveMarkers);
|
|
1723
|
+
this._decorationsTree1.acceptReplace(offset, length, textLength, forceMoveMarkers);
|
|
1724
|
+
this._injectedTextDecorationsTree.acceptReplace(offset, length, textLength, forceMoveMarkers);
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
function cleanClassName(className) {
|
|
1728
|
+
return className.replace(/[^a-z0-9\-_]/gi, ' ');
|
|
1729
|
+
}
|
|
1730
|
+
class DecorationOptions {
|
|
1731
|
+
constructor(options) {
|
|
1732
|
+
this.color = options.color || '';
|
|
1733
|
+
this.darkColor = options.darkColor || '';
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
class ModelDecorationOverviewRulerOptions extends DecorationOptions {
|
|
1737
|
+
constructor(options) {
|
|
1738
|
+
super(options);
|
|
1739
|
+
this._resolvedColor = null;
|
|
1740
|
+
this.position = (typeof options.position === 'number' ? options.position : OverviewRulerLane.Center);
|
|
1741
|
+
}
|
|
1742
|
+
getColor(theme) {
|
|
1743
|
+
if (!this._resolvedColor) {
|
|
1744
|
+
if (isDark(theme.type) && this.darkColor) {
|
|
1745
|
+
this._resolvedColor = this._resolveColor(this.darkColor, theme);
|
|
1746
|
+
}
|
|
1747
|
+
else {
|
|
1748
|
+
this._resolvedColor = this._resolveColor(this.color, theme);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
return this._resolvedColor;
|
|
1752
|
+
}
|
|
1753
|
+
invalidateCachedColor() {
|
|
1754
|
+
this._resolvedColor = null;
|
|
1755
|
+
}
|
|
1756
|
+
_resolveColor(color, theme) {
|
|
1757
|
+
if (typeof color === 'string') {
|
|
1758
|
+
return color;
|
|
1759
|
+
}
|
|
1760
|
+
const c = color ? theme.getColor(color.id) : null;
|
|
1761
|
+
if (!c) {
|
|
1762
|
+
return '';
|
|
1763
|
+
}
|
|
1764
|
+
return c.toString();
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
class ModelDecorationGlyphMarginOptions {
|
|
1768
|
+
constructor(options) {
|
|
1769
|
+
this.position = options?.position ?? GlyphMarginLane.Center;
|
|
1770
|
+
this.persistLane = options?.persistLane;
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
class ModelDecorationMinimapOptions extends DecorationOptions {
|
|
1774
|
+
constructor(options) {
|
|
1775
|
+
super(options);
|
|
1776
|
+
this.position = options.position;
|
|
1777
|
+
this.sectionHeaderStyle = options.sectionHeaderStyle ?? null;
|
|
1778
|
+
this.sectionHeaderText = options.sectionHeaderText ?? null;
|
|
1779
|
+
}
|
|
1780
|
+
getColor(theme) {
|
|
1781
|
+
if (!this._resolvedColor) {
|
|
1782
|
+
if (isDark(theme.type) && this.darkColor) {
|
|
1783
|
+
this._resolvedColor = this._resolveColor(this.darkColor, theme);
|
|
1784
|
+
}
|
|
1785
|
+
else {
|
|
1786
|
+
this._resolvedColor = this._resolveColor(this.color, theme);
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
return this._resolvedColor;
|
|
1790
|
+
}
|
|
1791
|
+
invalidateCachedColor() {
|
|
1792
|
+
this._resolvedColor = undefined;
|
|
1793
|
+
}
|
|
1794
|
+
_resolveColor(color, theme) {
|
|
1795
|
+
if (typeof color === 'string') {
|
|
1796
|
+
return Color.fromHex(color);
|
|
1797
|
+
}
|
|
1798
|
+
return theme.getColor(color.id);
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
class ModelDecorationInjectedTextOptions {
|
|
1802
|
+
static from(options) {
|
|
1803
|
+
if (options instanceof ModelDecorationInjectedTextOptions) {
|
|
1804
|
+
return options;
|
|
1805
|
+
}
|
|
1806
|
+
return new ModelDecorationInjectedTextOptions(options);
|
|
1807
|
+
}
|
|
1808
|
+
constructor(options) {
|
|
1809
|
+
this.content = options.content || '';
|
|
1810
|
+
this.tokens = options.tokens ?? null;
|
|
1811
|
+
this.inlineClassName = options.inlineClassName || null;
|
|
1812
|
+
this.inlineClassNameAffectsLetterSpacing = options.inlineClassNameAffectsLetterSpacing || false;
|
|
1813
|
+
this.attachedData = options.attachedData || null;
|
|
1814
|
+
this.cursorStops = options.cursorStops || null;
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
class ModelDecorationOptions {
|
|
1818
|
+
static register(options) {
|
|
1819
|
+
return new ModelDecorationOptions(options);
|
|
1820
|
+
}
|
|
1821
|
+
static createDynamic(options) {
|
|
1822
|
+
return new ModelDecorationOptions(options);
|
|
1823
|
+
}
|
|
1824
|
+
constructor(options) {
|
|
1825
|
+
this.description = options.description;
|
|
1826
|
+
this.blockClassName = options.blockClassName ? cleanClassName(options.blockClassName) : null;
|
|
1827
|
+
this.blockDoesNotCollapse = options.blockDoesNotCollapse ?? null;
|
|
1828
|
+
this.blockIsAfterEnd = options.blockIsAfterEnd ?? null;
|
|
1829
|
+
this.blockPadding = options.blockPadding ?? null;
|
|
1830
|
+
this.stickiness = options.stickiness || 0 /* model.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges */;
|
|
1831
|
+
this.zIndex = options.zIndex || 0;
|
|
1832
|
+
this.className = options.className ? cleanClassName(options.className) : null;
|
|
1833
|
+
this.shouldFillLineOnLineBreak = options.shouldFillLineOnLineBreak ?? null;
|
|
1834
|
+
this.hoverMessage = options.hoverMessage || null;
|
|
1835
|
+
this.glyphMarginHoverMessage = options.glyphMarginHoverMessage || null;
|
|
1836
|
+
this.lineNumberHoverMessage = options.lineNumberHoverMessage || null;
|
|
1837
|
+
this.isWholeLine = options.isWholeLine || false;
|
|
1838
|
+
this.lineHeight = options.lineHeight ? Math.min(options.lineHeight, LINE_HEIGHT_CEILING) : null;
|
|
1839
|
+
this.fontSize = options.fontSize || null;
|
|
1840
|
+
this.affectsFont = !!options.fontSize || !!options.fontFamily || !!options.fontWeight || !!options.fontStyle;
|
|
1841
|
+
this.showIfCollapsed = options.showIfCollapsed || false;
|
|
1842
|
+
this.collapseOnReplaceEdit = options.collapseOnReplaceEdit || false;
|
|
1843
|
+
this.overviewRuler = options.overviewRuler ? new ModelDecorationOverviewRulerOptions(options.overviewRuler) : null;
|
|
1844
|
+
this.minimap = options.minimap ? new ModelDecorationMinimapOptions(options.minimap) : null;
|
|
1845
|
+
this.glyphMargin = options.glyphMarginClassName ? new ModelDecorationGlyphMarginOptions(options.glyphMargin) : null;
|
|
1846
|
+
this.glyphMarginClassName = options.glyphMarginClassName ? cleanClassName(options.glyphMarginClassName) : null;
|
|
1847
|
+
this.linesDecorationsClassName = options.linesDecorationsClassName ? cleanClassName(options.linesDecorationsClassName) : null;
|
|
1848
|
+
this.lineNumberClassName = options.lineNumberClassName ? cleanClassName(options.lineNumberClassName) : null;
|
|
1849
|
+
this.linesDecorationsTooltip = options.linesDecorationsTooltip ? htmlAttributeEncodeValue(options.linesDecorationsTooltip) : null;
|
|
1850
|
+
this.firstLineDecorationClassName = options.firstLineDecorationClassName ? cleanClassName(options.firstLineDecorationClassName) : null;
|
|
1851
|
+
this.marginClassName = options.marginClassName ? cleanClassName(options.marginClassName) : null;
|
|
1852
|
+
this.inlineClassName = options.inlineClassName ? cleanClassName(options.inlineClassName) : null;
|
|
1853
|
+
this.inlineClassNameAffectsLetterSpacing = options.inlineClassNameAffectsLetterSpacing || false;
|
|
1854
|
+
this.beforeContentClassName = options.beforeContentClassName ? cleanClassName(options.beforeContentClassName) : null;
|
|
1855
|
+
this.afterContentClassName = options.afterContentClassName ? cleanClassName(options.afterContentClassName) : null;
|
|
1856
|
+
this.after = options.after ? ModelDecorationInjectedTextOptions.from(options.after) : null;
|
|
1857
|
+
this.before = options.before ? ModelDecorationInjectedTextOptions.from(options.before) : null;
|
|
1858
|
+
this.hideInCommentTokens = options.hideInCommentTokens ?? false;
|
|
1859
|
+
this.hideInStringTokens = options.hideInStringTokens ?? false;
|
|
1860
|
+
this.textDirection = options.textDirection ?? null;
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
ModelDecorationOptions.EMPTY = ModelDecorationOptions.register({ description: 'empty' });
|
|
1864
|
+
/**
|
|
1865
|
+
* The order carefully matches the values of the enum.
|
|
1866
|
+
*/
|
|
1867
|
+
const TRACKED_RANGE_OPTIONS = [
|
|
1868
|
+
ModelDecorationOptions.register({ description: 'tracked-range-always-grows-when-typing-at-edges', stickiness: 0 /* model.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges */ }),
|
|
1869
|
+
ModelDecorationOptions.register({ description: 'tracked-range-never-grows-when-typing-at-edges', stickiness: 1 /* model.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */ }),
|
|
1870
|
+
ModelDecorationOptions.register({ description: 'tracked-range-grows-only-when-typing-before', stickiness: 2 /* model.TrackedRangeStickiness.GrowsOnlyWhenTypingBefore */ }),
|
|
1871
|
+
ModelDecorationOptions.register({ description: 'tracked-range-grows-only-when-typing-after', stickiness: 3 /* model.TrackedRangeStickiness.GrowsOnlyWhenTypingAfter */ }),
|
|
1872
|
+
];
|
|
1873
|
+
function _normalizeOptions(options) {
|
|
1874
|
+
if (options instanceof ModelDecorationOptions) {
|
|
1875
|
+
return options;
|
|
1876
|
+
}
|
|
1877
|
+
return ModelDecorationOptions.createDynamic(options);
|
|
1878
|
+
}
|
|
1879
|
+
class LineHeightChangingDecoration {
|
|
1880
|
+
static toKey(obj) {
|
|
1881
|
+
return `${obj.ownerId};${obj.decorationId};${obj.lineNumber}`;
|
|
1882
|
+
}
|
|
1883
|
+
constructor(ownerId, decorationId, lineNumber, lineHeight) {
|
|
1884
|
+
this.ownerId = ownerId;
|
|
1885
|
+
this.decorationId = decorationId;
|
|
1886
|
+
this.lineNumber = lineNumber;
|
|
1887
|
+
this.lineHeight = lineHeight;
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
class LineFontChangingDecoration {
|
|
1891
|
+
static toKey(obj) {
|
|
1892
|
+
return `${obj.ownerId};${obj.decorationId};${obj.lineNumber}`;
|
|
1893
|
+
}
|
|
1894
|
+
constructor(ownerId, decorationId, lineNumber) {
|
|
1895
|
+
this.ownerId = ownerId;
|
|
1896
|
+
this.decorationId = decorationId;
|
|
1897
|
+
this.lineNumber = lineNumber;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
class DidChangeDecorationsEmitter extends Disposable {
|
|
1901
|
+
constructor(handleBeforeFire) {
|
|
1902
|
+
super();
|
|
1903
|
+
this.handleBeforeFire = handleBeforeFire;
|
|
1904
|
+
this._actual = this._register(new Emitter());
|
|
1905
|
+
this.event = this._actual.event;
|
|
1906
|
+
this._affectedInjectedTextLines = null;
|
|
1907
|
+
this._affectedLineHeights = null;
|
|
1908
|
+
this._affectedFontLines = null;
|
|
1909
|
+
this._deferredCnt = 0;
|
|
1910
|
+
this._shouldFireDeferred = false;
|
|
1911
|
+
this._affectsMinimap = false;
|
|
1912
|
+
this._affectsOverviewRuler = false;
|
|
1913
|
+
this._affectsGlyphMargin = false;
|
|
1914
|
+
this._affectsLineNumber = false;
|
|
1915
|
+
}
|
|
1916
|
+
beginDeferredEmit() {
|
|
1917
|
+
this._deferredCnt++;
|
|
1918
|
+
}
|
|
1919
|
+
endDeferredEmit() {
|
|
1920
|
+
this._deferredCnt--;
|
|
1921
|
+
if (this._deferredCnt === 0) {
|
|
1922
|
+
if (this._shouldFireDeferred) {
|
|
1923
|
+
this.doFire();
|
|
1924
|
+
}
|
|
1925
|
+
this._affectedInjectedTextLines?.clear();
|
|
1926
|
+
this._affectedInjectedTextLines = null;
|
|
1927
|
+
this._affectedLineHeights?.clear();
|
|
1928
|
+
this._affectedLineHeights = null;
|
|
1929
|
+
this._affectedFontLines?.clear();
|
|
1930
|
+
this._affectedFontLines = null;
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
recordLineAffectedByInjectedText(lineNumber) {
|
|
1934
|
+
if (!this._affectedInjectedTextLines) {
|
|
1935
|
+
this._affectedInjectedTextLines = new Set();
|
|
1936
|
+
}
|
|
1937
|
+
this._affectedInjectedTextLines.add(lineNumber);
|
|
1938
|
+
}
|
|
1939
|
+
recordLineAffectedByLineHeightChange(ownerId, decorationId, lineNumber, lineHeight) {
|
|
1940
|
+
if (!this._affectedLineHeights) {
|
|
1941
|
+
this._affectedLineHeights = new SetWithKey([], LineHeightChangingDecoration.toKey);
|
|
1942
|
+
}
|
|
1943
|
+
this._affectedLineHeights.add(new LineHeightChangingDecoration(ownerId, decorationId, lineNumber, lineHeight));
|
|
1944
|
+
}
|
|
1945
|
+
recordLineAffectedByFontChange(ownerId, decorationId, lineNumber) {
|
|
1946
|
+
if (!this._affectedFontLines) {
|
|
1947
|
+
this._affectedFontLines = new SetWithKey([], LineFontChangingDecoration.toKey);
|
|
1948
|
+
}
|
|
1949
|
+
this._affectedFontLines.add(new LineFontChangingDecoration(ownerId, decorationId, lineNumber));
|
|
1950
|
+
}
|
|
1951
|
+
checkAffectedAndFire(options) {
|
|
1952
|
+
this._affectsMinimap ||= !!options.minimap?.position;
|
|
1953
|
+
this._affectsOverviewRuler ||= !!options.overviewRuler?.color;
|
|
1954
|
+
this._affectsGlyphMargin ||= !!options.glyphMarginClassName;
|
|
1955
|
+
this._affectsLineNumber ||= !!options.lineNumberClassName;
|
|
1956
|
+
this.tryFire();
|
|
1957
|
+
}
|
|
1958
|
+
fire() {
|
|
1959
|
+
this._affectsMinimap = true;
|
|
1960
|
+
this._affectsOverviewRuler = true;
|
|
1961
|
+
this._affectsGlyphMargin = true;
|
|
1962
|
+
this.tryFire();
|
|
1963
|
+
}
|
|
1964
|
+
tryFire() {
|
|
1965
|
+
if (this._deferredCnt === 0) {
|
|
1966
|
+
this.doFire();
|
|
1967
|
+
}
|
|
1968
|
+
else {
|
|
1969
|
+
this._shouldFireDeferred = true;
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
doFire() {
|
|
1973
|
+
this.handleBeforeFire(this._affectedInjectedTextLines, this._affectedLineHeights, this._affectedFontLines);
|
|
1974
|
+
const event = {
|
|
1975
|
+
affectsMinimap: this._affectsMinimap,
|
|
1976
|
+
affectsOverviewRuler: this._affectsOverviewRuler,
|
|
1977
|
+
affectsGlyphMargin: this._affectsGlyphMargin,
|
|
1978
|
+
affectsLineNumber: this._affectsLineNumber,
|
|
1979
|
+
};
|
|
1980
|
+
this._shouldFireDeferred = false;
|
|
1981
|
+
this._affectsMinimap = false;
|
|
1982
|
+
this._affectsOverviewRuler = false;
|
|
1983
|
+
this._affectsGlyphMargin = false;
|
|
1984
|
+
this._actual.fire(event);
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
//#endregion
|
|
1988
|
+
class DidChangeContentEmitter extends Disposable {
|
|
1989
|
+
constructor() {
|
|
1990
|
+
super();
|
|
1991
|
+
/**
|
|
1992
|
+
* Both `fastEvent` and `slowEvent` work the same way and contain the same events, but first we invoke `fastEvent` and then `slowEvent`.
|
|
1993
|
+
*/
|
|
1994
|
+
this._fastEmitter = this._register(new Emitter());
|
|
1995
|
+
this.fastEvent = this._fastEmitter.event;
|
|
1996
|
+
this._slowEmitter = this._register(new Emitter());
|
|
1997
|
+
this.slowEvent = this._slowEmitter.event;
|
|
1998
|
+
this._deferredCnt = 0;
|
|
1999
|
+
this._deferredEvent = null;
|
|
2000
|
+
}
|
|
2001
|
+
beginDeferredEmit() {
|
|
2002
|
+
this._deferredCnt++;
|
|
2003
|
+
}
|
|
2004
|
+
endDeferredEmit(resultingSelection = null) {
|
|
2005
|
+
this._deferredCnt--;
|
|
2006
|
+
if (this._deferredCnt === 0) {
|
|
2007
|
+
if (this._deferredEvent !== null) {
|
|
2008
|
+
this._deferredEvent.rawContentChangedEvent.resultingSelection = resultingSelection;
|
|
2009
|
+
const e = this._deferredEvent;
|
|
2010
|
+
this._deferredEvent = null;
|
|
2011
|
+
this._fastEmitter.fire(e);
|
|
2012
|
+
this._slowEmitter.fire(e);
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
fire(e) {
|
|
2017
|
+
if (this._deferredCnt > 0) {
|
|
2018
|
+
if (this._deferredEvent) {
|
|
2019
|
+
this._deferredEvent = this._deferredEvent.merge(e);
|
|
2020
|
+
}
|
|
2021
|
+
else {
|
|
2022
|
+
this._deferredEvent = e;
|
|
2023
|
+
}
|
|
2024
|
+
return;
|
|
2025
|
+
}
|
|
2026
|
+
this._fastEmitter.fire(e);
|
|
2027
|
+
this._slowEmitter.fire(e);
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
export { ModelDecorationGlyphMarginOptions, ModelDecorationInjectedTextOptions, ModelDecorationMinimapOptions, ModelDecorationOptions, ModelDecorationOverviewRulerOptions, TextModel, createTextBuffer, createTextBufferFactory, createTextBufferFactoryFromSnapshot, indentOfLine };
|