304
305
constructor(
306
>
source: string | model.ITextBufferFactory,
textModel.ts
307
>
languageIdOrSelection: string | ILanguageSelection,
308
>
creationOptions: model.ITextModelCreationOptions,
309
>
associatedResource: URI | null = null,
310
>
@IUndoRedoService private readonly _undoRedoService: IUndoRedoService,
311
>
@ILanguageService private readonly _languageService: ILanguageService,
312
>
@ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService,
313
>
@IInstantiationService private readonly instantiationService: IInstantiationService
314
>
) {
315
>
super();
316
>
317
>
// Generate a new unique model id
318
>
MODEL_ID++;
319
>
this.id = '$model' + MODEL_ID;
320
>
this.isForSimpleWidget = creationOptions.isForSimpleWidget;
321
>
if (typeof associatedResource === 'undefined' || associatedResource === null) {
322
this._associatedResource = URI.parse('inmemory://model/' + MODEL_ID);
324
this._associatedResource = associatedResource;
325
}
327
>
328
>
const { textBuffer, disposable } = createTextBuffer(source, creationOptions.defaultEOL);
329
>
this._buffer = textBuffer;
330
>
this._bufferDisposable = disposable;
331
>
332
>
const bufferLineCount = this._buffer.getLineCount();
333
>
const bufferTextLength = this._buffer.getValueLengthInRange(new Range(1, 1, bufferLineCount, this._buffer.getLineLength(bufferLineCount) + 1), model.EndOfLinePreference.TextDefined);
334
>
335
>
// !!! Make a decision in the ctor and permanently respect this decision !!!
336
>
// If a model is too large at construction time, it will never get tokenized,
337
>
// under no circumstances.
338
>
if (creationOptions.largeFileOptimizations) {
339
>
this._isTooLargeForTokenization = (
340
>
(bufferTextLength > TextModel.LARGE_FILE_SIZE_THRESHOLD)
341
>
|| (bufferLineCount > TextModel.LARGE_FILE_LINE_COUNT_THRESHOLD)
342
>
);
343
>
344
>
this._isTooLargeForHeapOperation = bufferTextLength > TextModel.LARGE_FILE_HEAP_OPERATION_THRESHOLD;
345
>
} else {
346
this._isTooLargeForTokenization = false;
347
this._isTooLargeForHeapOperation = false;
348
}
350
>
this._options = TextModel.resolveOptions(this._buffer, creationOptions);
351
>
352
>
const languageId = (typeof languageIdOrSelection === 'string' ? languageIdOrSelection : languageIdOrSelection.languageId);
353
>
if (typeof languageIdOrSelection !== 'string') {
354
this._languageSelectionListener.value = languageIdOrSelection.onDidChange(() => this._setLanguage(languageIdOrSelection.languageId));
355
}
357
>
this._bracketPairs = this._register(new BracketPairsTextModelPart(this, this._languageConfigurationService));
358
>
this._guidesTextModelPart = this._register(new GuidesTextModelPart(this, this._languageConfigurationService));
359
>
this._decorationProvider = this._register(new ColorizedBracketPairsDecorationProvider(this));
360
>
this._tokenizationTextModelPart = this.instantiationService.createInstance(TokenizationTextModelPart,
361
>
this,
362
>
this._bracketPairs,
363
>
languageId,
364
>
this._attachedViews
365
>
);
366
>
this._fontTokenDecorationsProvider = this._register(new TokenizationFontDecorationProvider(this, this._tokenizationTextModelPart));
367
>
368
>
this._isTooLargeForSyncing = (bufferTextLength > TextModel._MODEL_SYNC_LIMIT);
369
>
370
>
this._versionId = 1;
371
>
this._alternativeVersionId = 1;
372
>
this._initialUndoRedoSnapshot = null;
373
>
374
>
this._isDisposed = false;
375
>
this.__isDisposing = false;
376
>
377
>
this._instanceId = strings.singleLetterHash(MODEL_ID);
378
>
this._lastDecorationId = 0;
379
>
this._decorations = Object.create(null);
380
>
this._decorationsTree = new DecorationsTrees();
381
>
382
>
this._commandManager = new EditStack(this, this._undoRedoService);
383
>
this._isUndoing = false;
384
>
this._isRedoing = false;
385
>
this._trimAutoWhitespaceLines = null;
386
>
387
>
388
>
this._register(this._decorationProvider.onDidChange(() => {
389
this._onDidChangeDecorations.beginDeferredEmit();
390
this._onDidChangeDecorations.fire();
391
this._onDidChangeDecorations.endDeferredEmit();
393
>
this._register(this._fontTokenDecorationsProvider.onDidChangeLineHeight((affectedLineHeights) => {
394
this._onDidChangeDecorations.beginDeferredEmit();
395
this._onDidChangeDecorations.fire();
396
this._fireOnDidChangeLineHeight(affectedLineHeights);
397
this._onDidChangeDecorations.endDeferredEmit();
399
>
this._register(this._fontTokenDecorationsProvider.onDidChangeFont((affectedFontLines) => {
400
this._onDidChangeDecorations.beginDeferredEmit();
401
this._onDidChangeDecorations.fire();
402
this._fireOnDidChangeFont(affectedFontLines);
403
this._onDidChangeDecorations.endDeferredEmit();
405
>
406
>
this._languageService.requestRichLanguageFeatures(languageId);
407
>
408
>
this._register(this._languageConfigurationService.onDidChange(e => {
409
this._bracketPairs.handleLanguageConfigurationServiceChange(e);
410
this._tokenizationTextModelPart.handleLanguageConfigurationServiceChange(e);
412
>
}
413
414
public override dispose(): void {
416
>
this._onWillDispose.fire();
417
>
this._tokenizationTextModelPart.dispose();
418
>
this._isDisposed = true;
419
>
super.dispose();
420
>
this._bufferDisposable.dispose();
421
>
this.__isDisposing = false;
422
>
// Manually release reference to previous text buffer to avoid large leaks
423
>
// in case someone leaks a TextModel reference
424
>
const emptyDisposedTextBuffer = new PieceTreeTextBuffer([], '', '\n', false, false, true, true);
425
>
emptyDisposedTextBuffer.dispose();
426
>
this._buffer = emptyDisposedTextBuffer;
427
>
this._bufferDisposable = Disposable.None;
428
>
}
429
430
_hasListeners(): boolean {