diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index 13b4ede0aee..9f25ed1118f 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -12,7 +12,6 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { Position, IPosition } from 'vs/editor/common/core/position'; import { Range, IRange } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; -import { ITextSource } from 'vs/editor/common/model/textSource'; import { ModelRawContentChangedEvent, IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelOptionsChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent, IModelContentChange, ModelRawChange } from 'vs/editor/common/model/textModelEvents'; import { ThemeColor } from 'vs/platform/theme/common/themeService'; @@ -490,7 +489,7 @@ export interface ITextModel { * Replace the entire text buffer value contained in this model. * @internal */ - setValueFromTextSource(newValue: ITextSource): void; + setValueFromTextBuffer(newValue: ITextBuffer): void; /** * Get the text stored in this model. @@ -509,7 +508,7 @@ export interface ITextModel { * Check if the raw text stored in this model equals another raw text. * @internal */ - equals(other: ITextSource): boolean; + equalsTextBuffer(other: ITextBuffer): boolean; /** * Get the text in a certain range. @@ -1052,14 +1051,23 @@ export interface ITextModel { * @internal */ export interface ITextBufferBuilder { - build(defaultEOL: DefaultEndOfLine): ITextBuffer; + acceptChunk(chunk: string): void; + finish(): ITextBufferFactory; +} + +/** + * @internal + */ +export interface ITextBufferFactory { + create(defaultEOL: DefaultEndOfLine): ITextBuffer; + getFirstLineText(lengthLimit: number): string; } /** * @internal */ export interface ITextBuffer { - equals(other: ITextSource): boolean; + equals(other: ITextBuffer): boolean; mightContainRTL(): boolean; mightContainNonBasicASCII(): boolean; getBOM(): string; diff --git a/src/vs/editor/common/model/textBuffer.ts b/src/vs/editor/common/model/textBuffer.ts index 67c3331f524..f9665622ec6 100644 --- a/src/vs/editor/common/model/textBuffer.ts +++ b/src/vs/editor/common/model/textBuffer.ts @@ -11,18 +11,21 @@ import * as arrays from 'vs/base/common/arrays'; import { ITextSource, IRawTextSource, TextSource } from 'vs/editor/common/model/textSource'; import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer'; import { ModelRawChange, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/model/textModelEvents'; -import { ISingleEditOperationIdentifier, IIdentifiedSingleEditOperation, EndOfLinePreference, ITextBuffer, ApplyEditsResult, IInternalModelContentChange, ITextBufferBuilder, DefaultEndOfLine } from 'vs/editor/common/model'; +import { ISingleEditOperationIdentifier, IIdentifiedSingleEditOperation, EndOfLinePreference, ITextBuffer, ApplyEditsResult, IInternalModelContentChange, ITextBufferFactory, DefaultEndOfLine } from 'vs/editor/common/model'; -export class TextBufferBuilder implements ITextBufferBuilder { +export class TextBufferFactory implements ITextBufferFactory { - constructor(private readonly textSource: IRawTextSource) { + constructor(public readonly rawTextSource: IRawTextSource) { } - public build(defaultEOL: DefaultEndOfLine): ITextBuffer { - const textSource = TextSource.fromRawTextSource(this.textSource, defaultEOL); + public create(defaultEOL: DefaultEndOfLine): ITextBuffer { + const textSource = TextSource.fromRawTextSource(this.rawTextSource, defaultEOL); return new TextBuffer(textSource); } + public getFirstLineText(lengthLimit: number): string { + return this.rawTextSource.lines[0].substr(0, lengthLimit); + } } export interface IValidatedEditOperation { @@ -64,18 +67,21 @@ export class TextBuffer implements ITextBuffer { this._lineStarts = new PrefixSumComputer(lineStartValues); } - public equals(other: ITextSource): boolean { - if (this._BOM !== other.BOM) { + public equals(other: ITextBuffer): boolean { + if (!(other instanceof TextBuffer)) { return false; } - if (this._EOL !== other.EOL) { + if (this._BOM !== other._BOM) { return false; } - if (this._lines.length !== other.lines.length) { + if (this._EOL !== other._EOL) { + return false; + } + if (this._lines.length !== other._lines.length) { return false; } for (let i = 0, len = this._lines.length; i < len; i++) { - if (this._lines[i] !== other.lines[i]) { + if (this._lines[i] !== other._lines[i]) { return false; } } diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index ceccc0e4c91..a03cdcdb4f3 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -8,7 +8,7 @@ import URI from 'vs/base/common/uri'; import Event, { Emitter } from 'vs/base/common/event'; import * as model from 'vs/editor/common/model'; import { LanguageIdentifier, TokenizationRegistry, LanguageId } from 'vs/editor/common/modes'; -import { IRawTextSource, RawTextSource, ITextSource, TextSource } from 'vs/editor/common/model/textSource'; +import { RawTextSource } from 'vs/editor/common/model/textSource'; import { EditStack } from 'vs/editor/common/model/editStack'; import { Range, IRange } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; @@ -32,7 +32,17 @@ import { ModelLinesTokens, ModelTokensChangedEventBuilder } from 'vs/editor/comm import { guessIndentation } from 'vs/editor/common/model/indentationGuesser'; import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions'; import { TextModelSearch, SearchParams } from 'vs/editor/common/model/textModelSearch'; -import { TextBufferBuilder, TextBuffer } from 'vs/editor/common/model/textBuffer'; +import { TextBufferFactory } from 'vs/editor/common/model/textBuffer'; + +export function createTextBufferFactory(text: string): model.ITextBufferFactory { + const rawTextSource = RawTextSource.fromString(text); + return new TextBufferFactory(rawTextSource); +} + +export function createTextBuffer(value: string | model.ITextBufferFactory, defaultEOL: model.DefaultEndOfLine): model.ITextBuffer { + const factory = (typeof value === 'string' ? createTextBufferFactory(value) : value); + return factory.create(defaultEOL); +} let MODEL_ID = 0; @@ -69,7 +79,7 @@ export class TextModel extends Disposable implements model.ITextModel { }; public static createFromString(text: string, options: model.ITextModelCreationOptions = TextModel.DEFAULT_CREATION_OPTIONS, languageIdentifier: LanguageIdentifier = null, uri: URI = null): TextModel { - return new TextModel(RawTextSource.fromString(text), options, languageIdentifier, uri); + return new TextModel(text, options, languageIdentifier, uri); } public static resolveOptions(textBuffer: model.ITextBuffer, options: model.ITextModelCreationOptions): model.TextModelResolvedOptions { @@ -162,7 +172,7 @@ export class TextModel extends Disposable implements model.ITextModel { /*private*/_tokens: ModelLinesTokens; //#endregion - constructor(rawTextSource: IRawTextSource, creationOptions: model.ITextModelCreationOptions, languageIdentifier: LanguageIdentifier, associatedResource: URI = null) { + constructor(source: string | model.ITextBufferFactory, creationOptions: model.ITextModelCreationOptions, languageIdentifier: LanguageIdentifier, associatedResource: URI = null) { super(); // Generate a new unique model id @@ -175,8 +185,7 @@ export class TextModel extends Disposable implements model.ITextModel { } this._attachedEditorCount = 0; - const builder: model.ITextBufferBuilder = new TextBufferBuilder(rawTextSource); - this._buffer = builder.build(creationOptions.defaultEOL); + this._buffer = createTextBuffer(source, creationOptions.defaultEOL); this._options = TextModel.resolveOptions(this._buffer, creationOptions); @@ -259,7 +268,7 @@ export class TextModel extends Disposable implements model.ITextModel { } } - public equals(other: ITextSource): boolean { + public equalsTextBuffer(other: model.ITextBuffer): boolean { this._assertNotDisposed(); return this._buffer.equals(other); } @@ -278,8 +287,9 @@ export class TextModel extends Disposable implements model.ITextModel { // There's nothing to do return; } - const textSource = TextSource.fromString(value, this._options.defaultEOL); - this.setValueFromTextSource(textSource); + + const textBuffer = createTextBuffer(value, this._options.defaultEOL); + this.setValueFromTextBuffer(textBuffer); } private _createContentChanged2(startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number, rangeLength: number, text: string, isUndoing: boolean, isRedoing: boolean, isFlush: boolean): IModelContentChangedEvent { @@ -297,9 +307,9 @@ export class TextModel extends Disposable implements model.ITextModel { }; } - public setValueFromTextSource(newValue: ITextSource): void { + public setValueFromTextBuffer(textBuffer: model.ITextBuffer): void { this._assertNotDisposed(); - if (newValue === null) { + if (textBuffer === null) { // There's nothing to do return; } @@ -308,8 +318,7 @@ export class TextModel extends Disposable implements model.ITextModel { const endLineNumber = this.getLineCount(); const endColumn = this.getLineMaxColumn(endLineNumber); - // TODO - this._buffer = new TextBuffer(newValue); + this._buffer = textBuffer; this._increaseVersionId(); // Cancel tokenization, clear all tokens and begin tokenizing diff --git a/src/vs/editor/common/services/modelService.ts b/src/vs/editor/common/services/modelService.ts index 413c92786c7..fa2af295f44 100644 --- a/src/vs/editor/common/services/modelService.ts +++ b/src/vs/editor/common/services/modelService.ts @@ -8,18 +8,17 @@ import Event from 'vs/base/common/event'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { ITextModel, ITextModelCreationOptions } from 'vs/editor/common/model'; +import { ITextModel, ITextModelCreationOptions, ITextBufferFactory } from 'vs/editor/common/model'; import { IMode } from 'vs/editor/common/modes'; -import { IRawTextSource } from 'vs/editor/common/model/textSource'; export const IModelService = createDecorator('modelService'); export interface IModelService { _serviceBrand: any; - createModel(value: string | IRawTextSource, modeOrPromise: TPromise | IMode, resource: URI): ITextModel; + createModel(value: string | ITextBufferFactory, modeOrPromise: TPromise | IMode, resource: URI): ITextModel; - updateModel(model: ITextModel, value: string | IRawTextSource): void; + updateModel(model: ITextModel, value: string | ITextBufferFactory): void; setMode(model: ITextModel, modeOrPromise: TPromise | IMode): void; diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index 7ff8495c740..8b0fb7cab01 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -15,21 +15,20 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IMarker, IMarkerService } from 'vs/platform/markers/common/markers'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; -import { TextModel } from 'vs/editor/common/model/textModel'; +import { TextModel, createTextBuffer } from 'vs/editor/common/model/textModel'; import { IMode, LanguageIdentifier } from 'vs/editor/common/modes'; import { IModelService } from 'vs/editor/common/services/modelService'; import * as platform from 'vs/base/common/platform'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions'; import { PLAINTEXT_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/modesRegistry'; -import { IRawTextSource, TextSource, RawTextSource, ITextSource } from 'vs/editor/common/model/textSource'; import { IModelLanguageChangedEvent } from 'vs/editor/common/model/textModelEvents'; import { ClassName } from 'vs/editor/common/model/intervalTree'; import { ISequence, LcsDiff } from 'vs/base/common/diff/diff'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { themeColorFromId, ThemeColor } from 'vs/platform/theme/common/themeService'; import { overviewRulerWarning, overviewRulerError, overviewRulerInfo } from 'vs/editor/common/view/editorColorRegistry'; -import { ITextModel, IModelDeltaDecoration, IModelDecorationOptions, TrackedRangeStickiness, OverviewRulerLane, DefaultEndOfLine, ITextModelCreationOptions, EndOfLineSequence, IIdentifiedSingleEditOperation } from 'vs/editor/common/model'; +import { ITextModel, IModelDeltaDecoration, IModelDecorationOptions, TrackedRangeStickiness, OverviewRulerLane, DefaultEndOfLine, ITextModelCreationOptions, EndOfLineSequence, IIdentifiedSingleEditOperation, ITextBufferFactory, ITextBuffer } from 'vs/editor/common/model'; function MODEL_ID(resource: URI): string { return resource.toString(); @@ -355,19 +354,18 @@ export class ModelServiceImpl implements IModelService { // --- begin IModelService - private _createModelData(value: string | IRawTextSource, languageIdentifier: LanguageIdentifier, resource: URI): ModelData { + private _createModelData(value: string | ITextBufferFactory, languageIdentifier: LanguageIdentifier, resource: URI): ModelData { // create & save the model const options = this.getCreationOptions(languageIdentifier.language, resource); - const rawTextSource = (typeof value === 'string' ? RawTextSource.fromString(value) : value); - let model: TextModel = new TextModel(rawTextSource, options, languageIdentifier, resource); - let modelId = MODEL_ID(model.uri); + const model: TextModel = new TextModel(value, options, languageIdentifier, resource); + const modelId = MODEL_ID(model.uri); if (this._models[modelId]) { // There already exists a model with this id => this is a programmer error throw new Error('ModelService: Cannot add model because it already exists!'); } - let modelData = new ModelData( + const modelData = new ModelData( model, (model) => this._onWillDispose(model), (model, e) => this._onDidChangeLanguage(model, e) @@ -377,20 +375,20 @@ export class ModelServiceImpl implements IModelService { return modelData; } - public updateModel(model: ITextModel, value: string | IRawTextSource): void { - let options = this.getCreationOptions(model.getLanguageIdentifier().language, model.uri); - const textSource = TextSource.create(value, options.defaultEOL); + public updateModel(model: ITextModel, value: string | ITextBufferFactory): void { + const options = this.getCreationOptions(model.getLanguageIdentifier().language, model.uri); + const textBuffer = createTextBuffer(value, options.defaultEOL); // Return early if the text is already set in that form - if (model.equals(textSource)) { + if (model.equalsTextBuffer(textBuffer)) { return; } // Otherwise find a diff between the values and update model - model.setEOL(textSource.EOL === '\r\n' ? EndOfLineSequence.CRLF : EndOfLineSequence.LF); + model.setEOL(textBuffer.getEOL() === '\r\n' ? EndOfLineSequence.CRLF : EndOfLineSequence.LF); model.pushEditOperations( [new Selection(1, 1, 1, 1)], - ModelServiceImpl._computeEdits(model, textSource), + ModelServiceImpl._computeEdits(model, textBuffer), (inverseEditOperations: IIdentifiedSingleEditOperation[]) => [new Selection(1, 1, 1, 1)] ); } @@ -398,7 +396,7 @@ export class ModelServiceImpl implements IModelService { /** * Compute edits to bring `model` to the state of `textSource`. */ - public static _computeEdits(model: ITextModel, textSource: ITextSource): IIdentifiedSingleEditOperation[] { + public static _computeEdits(model: ITextModel, textBuffer: ITextBuffer): IIdentifiedSingleEditOperation[] { const modelLineSequence = new class implements ISequence { public getLength(): number { return model.getLineCount(); @@ -409,10 +407,10 @@ export class ModelServiceImpl implements IModelService { }; const textSourceLineSequence = new class implements ISequence { public getLength(): number { - return textSource.lines.length; + return textBuffer.getLineCount(); } public getElementHash(index: number): string { - return textSource.lines[index]; + return textBuffer.getLineContent(index + 1); } }; @@ -429,7 +427,7 @@ export class ModelServiceImpl implements IModelService { let lines: string[] = []; for (let j = 0; j < modifiedLength; j++) { - lines[j] = textSource.lines[modifiedStart + j]; + lines[j] = textBuffer.getLineContent(modifiedStart + j + 1); } let text = lines.join('\n'); @@ -485,7 +483,7 @@ export class ModelServiceImpl implements IModelService { return edits; } - public createModel(value: string | IRawTextSource, modeOrPromise: TPromise | IMode, resource: URI): ITextModel { + public createModel(value: string | ITextBufferFactory, modeOrPromise: TPromise | IMode, resource: URI): ITextModel { let modelData: ModelData; if (!modeOrPromise || TPromise.is(modeOrPromise)) { diff --git a/src/vs/editor/contrib/smartSelect/test/tokenSelectionSupport.test.ts b/src/vs/editor/contrib/smartSelect/test/tokenSelectionSupport.test.ts index e773a399966..a06b506123b 100644 --- a/src/vs/editor/contrib/smartSelect/test/tokenSelectionSupport.test.ts +++ b/src/vs/editor/contrib/smartSelect/test/tokenSelectionSupport.test.ts @@ -115,4 +115,4 @@ suite('TokenSelectionSupport', () => { // new Range(3, 19, 3, 20) ]); }); -}); \ No newline at end of file +}); diff --git a/src/vs/editor/test/common/model/editableTextModel.test.ts b/src/vs/editor/test/common/model/editableTextModel.test.ts index 28aa980c3e7..7905611c6d1 100644 --- a/src/vs/editor/test/common/model/editableTextModel.test.ts +++ b/src/vs/editor/test/common/model/editableTextModel.test.ts @@ -12,11 +12,11 @@ import { TextModel } from 'vs/editor/common/model/textModel'; import { MirrorTextModel } from 'vs/editor/common/model/mirrorTextModel'; import { assertSyncedModels, testApplyEditsWithSyncedModels } from 'vs/editor/test/common/model/editableTextModelTestUtils'; import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents'; -import { RawTextSource, TextSource } from 'vs/editor/common/model/textSource'; +import { TextSource } from 'vs/editor/common/model/textSource'; import { TextBuffer, IValidatedEditOperation } from 'vs/editor/common/model/textBuffer'; function createEditableTextModelFromString(text: string): TextModel { - return new TextModel(RawTextSource.fromString(text), TextModel.DEFAULT_CREATION_OPTIONS, null); + return new TextModel(text, TextModel.DEFAULT_CREATION_OPTIONS, null); } suite('EditorModel - EditableTextModel._getInverseEdits', () => { diff --git a/src/vs/editor/test/common/model/editableTextModelTestUtils.ts b/src/vs/editor/test/common/model/editableTextModelTestUtils.ts index 030f52f54c5..7f1fc466033 100644 --- a/src/vs/editor/test/common/model/editableTextModelTestUtils.ts +++ b/src/vs/editor/test/common/model/editableTextModelTestUtils.ts @@ -8,7 +8,6 @@ import * as assert from 'assert'; import { TextModel } from 'vs/editor/common/model/textModel'; import { MirrorTextModel } from 'vs/editor/common/model/mirrorTextModel'; import { Position } from 'vs/editor/common/core/position'; -import { RawTextSource } from 'vs/editor/common/model/textSource'; import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents'; import { EndOfLinePreference, IIdentifiedSingleEditOperation, EndOfLineSequence } from 'vs/editor/common/model'; @@ -81,7 +80,7 @@ function assertLineMapping(model: TextModel, msg: string): void { export function assertSyncedModels(text: string, callback: (model: TextModel, assertMirrorModels: () => void) => void, setup: (model: TextModel) => void = null): void { - var model = new TextModel(RawTextSource.fromString(text), TextModel.DEFAULT_CREATION_OPTIONS, null); + var model = new TextModel(text, TextModel.DEFAULT_CREATION_OPTIONS, null); model.setEOL(EndOfLineSequence.LF); assertLineMapping(model, 'model'); diff --git a/src/vs/editor/test/common/model/model.line.test.ts b/src/vs/editor/test/common/model/model.line.test.ts index 3a8baf6f4c8..1779b580b22 100644 --- a/src/vs/editor/test/common/model/model.line.test.ts +++ b/src/vs/editor/test/common/model/model.line.test.ts @@ -10,7 +10,6 @@ import { LanguageIdentifier, MetadataConsts } from 'vs/editor/common/modes'; import { Range } from 'vs/editor/common/core/range'; import { ViewLineToken, ViewLineTokenFactory } from 'vs/editor/test/common/core/viewLineToken'; import { TextModel } from 'vs/editor/common/model/textModel'; -import { RawTextSource } from 'vs/editor/common/model/textSource'; interface ILineEdit { startColumn: number; @@ -107,7 +106,7 @@ suite('ModelLinesTokens', () => { function testApplyEdits(initial: IBufferLineState[], edits: IEdit[], expected: IBufferLineState[]): void { const initialText = initial.map(el => el.text).join('\n'); - const model = new TextModel(RawTextSource.fromString(initialText), TextModel.DEFAULT_CREATION_OPTIONS, new LanguageIdentifier('test', 0)); + const model = new TextModel(initialText, TextModel.DEFAULT_CREATION_OPTIONS, new LanguageIdentifier('test', 0)); for (let lineIndex = 0; lineIndex < initial.length; lineIndex++) { const lineTokens = initial[lineIndex].tokens; const lineTextLength = model.getLineMaxColumn(lineIndex + 1) - 1; @@ -441,7 +440,7 @@ suite('ModelLinesTokens', () => { } test('insertion on empty line', () => { - const model = new TextModel(RawTextSource.fromString('some text'), TextModel.DEFAULT_CREATION_OPTIONS, new LanguageIdentifier('test', 0)); + const model = new TextModel('some text', TextModel.DEFAULT_CREATION_OPTIONS, new LanguageIdentifier('test', 0)); model._tokens._setTokens(0, 0, model.getLineMaxColumn(1) - 1, TestToken.toTokens([new TestToken(0, 1)])); model.applyEdits([{ diff --git a/src/vs/editor/test/common/model/textModelWithTokens.test.ts b/src/vs/editor/test/common/model/textModelWithTokens.test.ts index 122bdd03283..a9fae3df41a 100644 --- a/src/vs/editor/test/common/model/textModelWithTokens.test.ts +++ b/src/vs/editor/test/common/model/textModelWithTokens.test.ts @@ -16,7 +16,6 @@ import { IFoundBracket } from 'vs/editor/common/model'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { NULL_STATE } from 'vs/editor/common/modes/nullMode'; import { TokenizationResult2 } from 'vs/editor/common/core/token'; -import { RawTextSource } from 'vs/editor/common/model/textSource'; suite('TextModelWithTokens', () => { @@ -75,7 +74,7 @@ suite('TextModelWithTokens', () => { }); let model = new TextModel( - RawTextSource.fromString(contents.join('\n')), + contents.join('\n'), TextModel.DEFAULT_CREATION_OPTIONS, languageIdentifier ); diff --git a/src/vs/editor/test/common/services/modelService.test.ts b/src/vs/editor/test/common/services/modelService.test.ts index efbd24d596c..d6390a41656 100644 --- a/src/vs/editor/test/common/services/modelService.test.ts +++ b/src/vs/editor/test/common/services/modelService.test.ts @@ -10,8 +10,7 @@ import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; import URI from 'vs/base/common/uri'; import * as platform from 'vs/base/common/platform'; import { DefaultEndOfLine } from 'vs/editor/common/model'; -import { TextModel } from 'vs/editor/common/model/textModel'; -import { TextSource } from 'vs/editor/common/model/textSource'; +import { TextModel, createTextBuffer } from 'vs/editor/common/model/textModel'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { Range } from 'vs/editor/common/core/range'; import { CharCode } from 'vs/base/common/charCode'; @@ -55,7 +54,7 @@ suite('ModelService', () => { ].join('\n') ); - const textSource = TextSource.fromString( + const textBuffer = createTextBuffer( [ 'This is line One', //16 'and this is line number two', //27 @@ -65,7 +64,7 @@ suite('ModelService', () => { DefaultEndOfLine.LF ); - const actual = ModelServiceImpl._computeEdits(model, textSource); + const actual = ModelServiceImpl._computeEdits(model, textBuffer); assert.deepEqual(actual, [ EditOperation.replace(new Range(1, 1, 1, 17), 'This is line One') @@ -83,7 +82,7 @@ suite('ModelService', () => { ].join('\n') ); - const textSource = TextSource.fromString( + const textBuffer = createTextBuffer( [ 'This is line one', //16 'and this is line number two', //27 @@ -93,7 +92,7 @@ suite('ModelService', () => { DefaultEndOfLine.LF ); - const actual = ModelServiceImpl._computeEdits(model, textSource); + const actual = ModelServiceImpl._computeEdits(model, textBuffer); assert.deepEqual(actual, []); }); @@ -109,7 +108,7 @@ suite('ModelService', () => { ].join('\n') ); - const textSource = TextSource.fromString( + const textBuffer = createTextBuffer( [ 'This is line One', //16 'and this is line number two', //27 @@ -119,7 +118,7 @@ suite('ModelService', () => { DefaultEndOfLine.LF ); - const actual = ModelServiceImpl._computeEdits(model, textSource); + const actual = ModelServiceImpl._computeEdits(model, textBuffer); assert.deepEqual(actual, [ EditOperation.replace(new Range(1, 1, 1, 17), 'This is line One'), @@ -137,7 +136,7 @@ suite('ModelService', () => { ].join('\n') ); - const textSource = TextSource.fromString( + const textBuffer = createTextBuffer( [ 'package main', // 1 'func foo() {', // 2 @@ -147,7 +146,7 @@ suite('ModelService', () => { DefaultEndOfLine.LF ); - const actual = ModelServiceImpl._computeEdits(model, textSource); + const actual = ModelServiceImpl._computeEdits(model, textBuffer); assert.deepEqual(actual, [ EditOperation.replace(new Range(3, 2, 3, 2), '\n') @@ -272,11 +271,11 @@ suite('ModelService', () => { function assertComputeEdits(lines1: string[], lines2: string[]): void { const model = TextModel.createFromString(lines1.join('\n')); - const textSource = TextSource.fromString(lines2.join('\n'), DefaultEndOfLine.LF); + const textBuffer = createTextBuffer(lines2.join('\n'), DefaultEndOfLine.LF); // compute required edits // let start = Date.now(); - const edits = ModelServiceImpl._computeEdits(model, textSource); + const edits = ModelServiceImpl._computeEdits(model, textBuffer); // console.log(`took ${Date.now() - start} ms.`); // apply edits diff --git a/src/vs/workbench/api/electron-browser/mainThreadDocumentContentProviders.ts b/src/vs/workbench/api/electron-browser/mainThreadDocumentContentProviders.ts index 11167913152..4120a889395 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDocumentContentProviders.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDocumentContentProviders.ts @@ -7,11 +7,11 @@ import URI, { UriComponents } from 'vs/base/common/uri'; import { IDisposable } from 'vs/base/common/lifecycle'; import { TPromise } from 'vs/base/common/winjs.base'; -import { ITextModel } from 'vs/editor/common/model'; +import { ITextModel, DefaultEndOfLine } from 'vs/editor/common/model'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService'; import { MainThreadDocumentContentProvidersShape, ExtHostContext, ExtHostDocumentContentProvidersShape, MainContext, IExtHostContext } from '../node/extHost.protocol'; -import { ITextSource } from 'vs/editor/common/model/textSource'; +import { createTextBuffer } from 'vs/editor/common/model/textModel'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -63,23 +63,16 @@ export class MainThreadDocumentContentProviders implements MainThreadDocumentCon } } - $onVirtualDocumentChange(uri: UriComponents, value: ITextSource): void { + $onVirtualDocumentChange(uri: UriComponents, value: string): void { const model = this._modelService.getModel(URI.revive(uri)); if (!model) { return; } - const raw: ITextSource = { - lines: value.lines, - length: value.length, - BOM: value.BOM, - EOL: value.EOL, - containsRTL: value.containsRTL, - isBasicASCII: value.isBasicASCII, - }; + const textBuffer = createTextBuffer(value, DefaultEndOfLine.CRLF); - if (!model.equals(raw)) { - model.setValueFromTextSource(raw); + if (!model.equalsTextBuffer(textBuffer)) { + model.setValueFromTextBuffer(textBuffer); } } } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index b38936b9694..9ec2422972f 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -28,7 +28,6 @@ import { IProgressOptions, IProgressStep } from 'vs/platform/progress/common/pro import * as editorCommon from 'vs/editor/common/editorCommon'; import * as modes from 'vs/editor/common/modes'; -import { ITextSource } from 'vs/editor/common/model/textSource'; import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { IConfig } from 'vs/workbench/parts/debug/common/debug'; @@ -148,7 +147,7 @@ export interface MainThreadDecorationsShape extends IDisposable { export interface MainThreadDocumentContentProvidersShape extends IDisposable { $registerTextContentProvider(handle: number, scheme: string): void; $unregisterTextContentProvider(handle: number): void; - $onVirtualDocumentChange(uri: UriComponents, value: ITextSource): void; + $onVirtualDocumentChange(uri: UriComponents, value: string): void; } export interface MainThreadDocumentsShape extends IDisposable { diff --git a/src/vs/workbench/api/node/extHostDocumentContentProviders.ts b/src/vs/workbench/api/node/extHostDocumentContentProviders.ts index dda2f7962a2..b3fa054cd5d 100644 --- a/src/vs/workbench/api/node/extHostDocumentContentProviders.ts +++ b/src/vs/workbench/api/node/extHostDocumentContentProviders.ts @@ -60,7 +60,7 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro // broadcast event when content changed if (!document.equalLines(textSource)) { - return this._proxy.$onVirtualDocumentChange(uri, textSource); + return this._proxy.$onVirtualDocumentChange(uri, value); } }, onUnexpectedError); diff --git a/src/vs/workbench/common/editor/textEditorModel.ts b/src/vs/workbench/common/editor/textEditorModel.ts index dfd5d1abc23..524ffbdf8d6 100644 --- a/src/vs/workbench/common/editor/textEditorModel.ts +++ b/src/vs/workbench/common/editor/textEditorModel.ts @@ -5,7 +5,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { EndOfLinePreference, ITextModel } from 'vs/editor/common/model'; +import { EndOfLinePreference, ITextModel, ITextBufferFactory } from 'vs/editor/common/model'; import { IMode } from 'vs/editor/common/modes'; import { EditorModel } from 'vs/workbench/common/editor'; import URI from 'vs/base/common/uri'; @@ -13,7 +13,6 @@ import { ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IModelService } from 'vs/editor/common/services/modelService'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { IRawTextSource } from 'vs/editor/common/model/textSource'; /** * The base text editor model leverages the code editor model. This class is only intended to be subclassed and not instantiated. @@ -67,13 +66,13 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd /** * Creates the text editor model with the provided value, modeId (can be comma separated for multiple values) and optional resource URL. */ - protected createTextEditorModel(value: string | IRawTextSource, resource?: URI, modeId?: string): TPromise { + protected createTextEditorModel(value: string | ITextBufferFactory, resource?: URI, modeId?: string): TPromise { const firstLineText = this.getFirstLineText(value); const mode = this.getOrCreateMode(this.modeService, modeId, firstLineText); return TPromise.as(this.doCreateTextEditorModel(value, mode, resource)); } - private doCreateTextEditorModel(value: string | IRawTextSource, mode: TPromise, resource: URI): EditorModel { + private doCreateTextEditorModel(value: string | ITextBufferFactory, mode: TPromise, resource: URI): EditorModel { let model = resource && this.modelService.getModel(resource); if (!model) { model = this.modelService.createModel(value, mode, resource); @@ -91,7 +90,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd return this; } - protected getFirstLineText(value: string | IRawTextSource): string { + protected getFirstLineText(value: string | ITextBufferFactory): string { if (typeof value === 'string') { const firstLineText = value.substr(0, 100); @@ -107,7 +106,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd return firstLineText.substr(0, Math.min(crIndex, lfIndex)); } else { - return value.lines[0].substr(0, 100); + return value.getFirstLineText(100); } } @@ -123,7 +122,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd /** * Updates the text editor model with the provided value. If the value is the same as the model has, this is a no-op. */ - protected updateTextEditorModel(newValue: string | IRawTextSource): void { + protected updateTextEditorModel(newValue: string | ITextBufferFactory): void { if (!this.textEditorModel) { return; } diff --git a/src/vs/workbench/parts/welcome/walkThrough/node/walkThroughContentProvider.ts b/src/vs/workbench/parts/welcome/walkThrough/node/walkThroughContentProvider.ts index 28d890ba9bf..ea02659a15a 100644 --- a/src/vs/workbench/parts/welcome/walkThrough/node/walkThroughContentProvider.ts +++ b/src/vs/workbench/parts/welcome/walkThrough/node/walkThroughContentProvider.ts @@ -10,12 +10,12 @@ import URI from 'vs/base/common/uri'; import { ITextModelService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { ITextModel } from 'vs/editor/common/model'; +import { ITextModel, DefaultEndOfLine, EndOfLinePreference, ITextBufferFactory } from 'vs/editor/common/model'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { marked } from 'vs/base/common/marked/marked'; import { Schemas } from 'vs/base/common/network'; -import { IRawTextSource } from 'vs/editor/common/model/textSource'; +import { Range } from 'vs/editor/common/core/range'; export class WalkThroughContentProvider implements ITextModelContentProvider, IWorkbenchContribution { @@ -30,7 +30,7 @@ export class WalkThroughContentProvider implements ITextModelContentProvider, IW public provideTextContent(resource: URI): TPromise { const query = resource.query ? JSON.parse(resource.query) : {}; - const content: TPromise = (query.moduleId ? new TPromise((resolve, reject) => { + const content: TPromise = (query.moduleId ? new TPromise((resolve, reject) => { require([query.moduleId], content => { try { resolve(content.default()); @@ -81,7 +81,10 @@ export class WalkThroughSnippetContentProvider implements ITextModelContentProvi return ''; }; - const markdown = content.value.lines.join('\n'); + const textBuffer = content.value.create(DefaultEndOfLine.LF); + const lineCount = textBuffer.getLineCount(); + const range = new Range(1, 1, lineCount, textBuffer.getLineLength(lineCount) + 1); + const markdown = textBuffer.getValueInRange(range, EndOfLinePreference.TextDefined); marked(markdown, { renderer }); const modeId = this.modeService.getModeIdForLanguageName(languageName); diff --git a/src/vs/workbench/services/backup/common/backup.ts b/src/vs/workbench/services/backup/common/backup.ts index 25c3948dced..7228988ab14 100644 --- a/src/vs/workbench/services/backup/common/backup.ts +++ b/src/vs/workbench/services/backup/common/backup.ts @@ -9,7 +9,7 @@ import Uri from 'vs/base/common/uri'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { TPromise } from 'vs/base/common/winjs.base'; import { IResolveContentOptions, IUpdateContentOptions } from 'vs/platform/files/common/files'; -import { IRawTextSource } from 'vs/editor/common/model/textSource'; +import { ITextBufferFactory } from 'vs/editor/common/model'; export const IBackupFileService = createDecorator('backupFileService'); @@ -68,10 +68,10 @@ export interface IBackupFileService { * Parses backup raw text content into the content, removing the metadata that is also stored * in the file. * - * @param rawText The IRawTextProvider from a backup resource. + * @param textBufferFactory The ITextBufferFactory from a backup resource. * @return The backup file's backed up content. */ - parseBackupContent(textSource: IRawTextSource): string; + parseBackupContent(textBufferFactory: ITextBufferFactory): string; /** * Discards the backup associated with a resource if it exists.. diff --git a/src/vs/workbench/services/backup/node/backupFileService.ts b/src/vs/workbench/services/backup/node/backupFileService.ts index 6b4bb50f895..ff3543726ce 100644 --- a/src/vs/workbench/services/backup/node/backupFileService.ts +++ b/src/vs/workbench/services/backup/node/backupFileService.ts @@ -14,8 +14,8 @@ import { IBackupFileService, BACKUP_FILE_UPDATE_OPTIONS } from 'vs/workbench/ser import { IFileService } from 'vs/platform/files/common/files'; import { TPromise } from 'vs/base/common/winjs.base'; import { readToMatchingString } from 'vs/base/node/stream'; -import { TextSource, IRawTextSource } from 'vs/editor/common/model/textSource'; -import { DefaultEndOfLine } from 'vs/editor/common/model'; +import { Range } from 'vs/editor/common/core/range'; +import { DefaultEndOfLine, ITextBufferFactory, EndOfLinePreference } from 'vs/editor/common/model'; export interface IBackupFilesModel { resolve(backupRoot: string): TPromise; @@ -213,9 +213,12 @@ export class BackupFileService implements IBackupFileService { }); } - public parseBackupContent(rawTextSource: IRawTextSource): string { - const textSource = TextSource.fromRawTextSource(rawTextSource, DefaultEndOfLine.LF); - return textSource.lines.slice(1).join(textSource.EOL); // The first line of a backup text file is the file name + public parseBackupContent(textBufferFactory: ITextBufferFactory): string { + // The first line of a backup text file is the file name + const textBuffer = textBufferFactory.create(DefaultEndOfLine.LF); + const lineCount = textBuffer.getLineCount(); + const range = new Range(2, 1, lineCount, textBuffer.getLineLength(lineCount) + 1); + return textBuffer.getValueInRange(range, EndOfLinePreference.TextDefined); } public toBackupResource(resource: Uri): Uri { diff --git a/src/vs/workbench/services/backup/test/node/backupFileService.test.ts b/src/vs/workbench/services/backup/test/node/backupFileService.test.ts index 66be679cdde..84ae8794ec7 100644 --- a/src/vs/workbench/services/backup/test/node/backupFileService.test.ts +++ b/src/vs/workbench/services/backup/test/node/backupFileService.test.ts @@ -16,7 +16,7 @@ import pfs = require('vs/base/node/pfs'); import Uri from 'vs/base/common/uri'; import { BackupFileService, BackupFilesModel } from 'vs/workbench/services/backup/node/backupFileService'; import { FileService } from 'vs/workbench/services/files/node/fileService'; -import { RawTextSource } from 'vs/editor/common/model/textSource'; +import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { TestContextService, TestTextResourceConfigurationService, getRandomTestPath, TestLifecycleService } from 'vs/workbench/test/workbenchTestServices'; import { Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; @@ -220,8 +220,8 @@ suite('BackupFileService', () => { test('parseBackupContent', () => { test('should separate metadata from content', () => { - const textSource = RawTextSource.fromString('metadata\ncontent'); - assert.equal(service.parseBackupContent(textSource), 'content'); + const textBufferFactory = createTextBufferFactory('metadata\ncontent'); + assert.equal(service.parseBackupContent(textBufferFactory), 'content'); }); }); }); diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index edeb287757f..62ae927ce42 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -30,7 +30,7 @@ import { IModeService } from 'vs/editor/common/services/modeService'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { RunOnceScheduler } from 'vs/base/common/async'; -import { IRawTextSource } from 'vs/editor/common/model/textSource'; +import { ITextBufferFactory } from 'vs/editor/common/model'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; /** @@ -425,7 +425,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return this.doCreateTextModel(content.resource, content.value, backup); } - private doUpdateTextModel(value: string | IRawTextSource): TPromise { + private doUpdateTextModel(value: string | ITextBufferFactory): TPromise { diag('load() - updated text editor model', this.resource, new Date()); // Ensure we are not tracking a stale state @@ -445,7 +445,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return TPromise.as(this); } - private doCreateTextModel(resource: URI, value: string | IRawTextSource, backup: URI): TPromise { + private doCreateTextModel(resource: URI, value: string | ITextBufferFactory, backup: URI): TPromise { diag('load() - created text editor model', this.resource, new Date()); this.createTextEditorModelPromise = this.doLoadBackup(backup).then(backupContent => { diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index ebc3ebae4f6..4be8ffb329e 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -12,7 +12,7 @@ import { IEncodingSupport, ConfirmResult } from 'vs/workbench/common/editor'; import { IBaseStat, IResolveContentOptions } from 'vs/platform/files/common/files'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ITextEditorModel } from 'vs/editor/common/services/resolverService'; -import { IRawTextSource } from 'vs/editor/common/model/textSource'; +import { ITextBufferFactory } from 'vs/editor/common/model'; import { IRevertOptions } from 'vs/platform/editor/common/editor'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; @@ -131,7 +131,7 @@ export interface IRawTextContent extends IBaseStat { /** * The line grouped content of a text file. */ - value: IRawTextSource; + value: ITextBufferFactory; /** * The encoding of the content if known. diff --git a/src/vs/workbench/services/textfile/electron-browser/modelBuilder.ts b/src/vs/workbench/services/textfile/electron-browser/modelBuilder.ts index f71ab5bc209..368b4b1ec18 100644 --- a/src/vs/workbench/services/textfile/electron-browser/modelBuilder.ts +++ b/src/vs/workbench/services/textfile/electron-browser/modelBuilder.ts @@ -8,14 +8,10 @@ import { IStringStream } from 'vs/platform/files/common/files'; import * as strings from 'vs/base/common/strings'; import { TPromise } from 'vs/base/common/winjs.base'; import { CharCode } from 'vs/base/common/charCode'; -import { IRawTextSource } from 'vs/editor/common/model/textSource'; +import { ITextBufferFactory, ITextBufferBuilder } from 'vs/editor/common/model'; +import { TextBufferFactory } from 'vs/editor/common/model/textBuffer'; const AVOID_SLICED_STRINGS = true; - -export interface ModelBuilderResult { - readonly value: IRawTextSource; -} - const PREALLOC_BUFFER_CHARS = 1000; const emptyString = ''; @@ -82,21 +78,19 @@ class ModelLineBasedBuilder { } } - public finish(length: number, carriageReturnCnt: number, containsRTL: boolean, isBasicASCII: boolean): ModelBuilderResult { - return { - value: { - BOM: this.BOM, - lines: this.lines, - length, - containsRTL: containsRTL, - totalCRCount: carriageReturnCnt, - isBasicASCII, - } - }; + public finish(length: number, carriageReturnCnt: number, containsRTL: boolean, isBasicASCII: boolean): TextBufferFactory { + return new TextBufferFactory({ + BOM: this.BOM, + lines: this.lines, + length, + containsRTL: containsRTL, + totalCRCount: carriageReturnCnt, + isBasicASCII, + }); } } -export class ModelBuilder { +export class ModelBuilder implements ITextBufferBuilder { private leftoverPrevChunk: string; private leftoverEndsInCR: boolean; @@ -106,8 +100,8 @@ export class ModelBuilder { private containsRTL: boolean; private isBasicASCII: boolean; - public static fromStringStream(stream: IStringStream): TPromise { - return new TPromise((c, e, p) => { + public static fromStringStream(stream: IStringStream): TPromise { + return new TPromise((c, e, p) => { let done = false; let builder = new ModelBuilder(); @@ -190,7 +184,7 @@ export class ModelBuilder { this.leftoverPrevChunk = lines[lines.length - 1]; } - public finish(): ModelBuilderResult { + public finish(): TextBufferFactory { let finalLines = [this.leftoverPrevChunk]; if (this.leftoverEndsInCR) { finalLines.push(''); diff --git a/src/vs/workbench/services/textfile/electron-browser/textFileService.ts b/src/vs/workbench/services/textfile/electron-browser/textFileService.ts index 396104c417c..0924f891755 100644 --- a/src/vs/workbench/services/textfile/electron-browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/electron-browser/textFileService.ts @@ -63,7 +63,7 @@ export class TextFileService extends AbstractTextFileService { mtime: streamContent.mtime, etag: streamContent.etag, encoding: streamContent.encoding, - value: res.value + value: res }; return r; }); diff --git a/src/vs/workbench/services/textfile/test/modelBuilder.test.ts b/src/vs/workbench/services/textfile/test/modelBuilder.test.ts index f07594cadc9..5ee66240d18 100644 --- a/src/vs/workbench/services/textfile/test/modelBuilder.test.ts +++ b/src/vs/workbench/services/textfile/test/modelBuilder.test.ts @@ -20,9 +20,7 @@ export function testModelBuilder(chunks: string[], opts: ITextModelCreationOptio } let actual = builder.finish(); - let actualTextSource = actual.value; - - assert.deepEqual(actualTextSource, expectedTextSource); + assert.deepEqual(actual.rawTextSource, expectedTextSource); } suite('ModelBuilder', () => { diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index ee0ce7a7873..cf38082c617 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -47,7 +47,7 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { IWindowsService, IWindowService, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; -import { RawTextSource, IRawTextSource } from 'vs/editor/common/model/textSource'; +import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { isLinux } from 'vs/base/common/platform'; @@ -61,6 +61,8 @@ import { ICommandAction } from 'vs/platform/actions/common/actions'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; +import { ITextBufferFactory, DefaultEndOfLine, EndOfLinePreference } from 'vs/editor/common/model'; +import { Range } from 'vs/editor/common/core/range'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, void 0); @@ -203,15 +205,14 @@ export class TestTextFileService extends TextFileService { return TPromise.wrapError(error); } - return this.fileService.resolveContent(resource, options).then((content) => { - const textSource = RawTextSource.fromString(content.value); - return { + return this.fileService.resolveContent(resource, options).then((content): IRawTextContent => { + return { resource: content.resource, name: content.name, mtime: content.mtime, etag: content.etag, encoding: content.encoding, - value: textSource + value: createTextBufferFactory(content.value) }; }); } @@ -864,8 +865,11 @@ export class TestBackupFileService implements IBackupFileService { return TPromise.as([]); } - public parseBackupContent(rawText: IRawTextSource): string { - return rawText.lines.join('\n'); + public parseBackupContent(textBufferFactory: ITextBufferFactory): string { + const textBuffer = textBufferFactory.create(DefaultEndOfLine.LF); + const lineCount = textBuffer.getLineCount(); + const range = new Range(1, 1, lineCount, textBuffer.getLineLength(lineCount) + 1); + return textBuffer.getValueInRange(range, EndOfLinePreference.TextDefined); } public discardResourceBackup(resource: URI): TPromise {