diff --git a/src/vs/editor/common/viewModel/splitLinesCollection.ts b/src/vs/editor/common/viewModel/splitLinesCollection.ts index 7c40b262f096d..5354816d18808 100644 --- a/src/vs/editor/common/viewModel/splitLinesCollection.ts +++ b/src/vs/editor/common/viewModel/splitLinesCollection.ts @@ -5,11 +5,12 @@ 'use strict'; import { Position } from 'vs/editor/common/core/position'; +import { Selection } from 'vs/editor/common/core/selection'; import { Range } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { LineTokens } from 'vs/editor/common/core/lineTokens'; import { PrefixSumComputerWithCache } from 'vs/editor/common/viewModel/prefixSumComputer'; -import { ViewLineData } from 'vs/editor/common/viewModel/viewModel'; +import { ViewLineData, ICoordinatesConverter } from 'vs/editor/common/viewModel/viewModel'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { WrappingIndent } from 'vs/editor/common/config/editorOptions'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations'; @@ -58,7 +59,92 @@ export interface ISplitLine { getViewPositionOfModelPosition(deltaLineNumber: number, inputColumn: number): Position; } -export class SplitLinesCollection { +export interface IViewModelLinesCollection { + createCoordinatesConverter(): ICoordinatesConverter; + + dispose(): void; + + setWrappingSettings(wrappingIndent: WrappingIndent, wrappingColumn: number, columnsForFullWidthChar: number): boolean; + setTabSize(newTabSize: number): boolean; + setHiddenAreas(_ranges: Range[]): boolean; + + onModelFlushed(): void; + onModelLinesDeleted(versionId: number, fromLineNumber: number, toLineNumber: number): viewEvents.ViewLinesDeletedEvent; + onModelLinesInserted(versionId: number, fromLineNumber: number, toLineNumber: number, text: string[]): viewEvents.ViewLinesInsertedEvent; + onModelLineChanged(versionId: number, lineNumber: number, newText: string): [boolean, viewEvents.ViewLinesChangedEvent, viewEvents.ViewLinesInsertedEvent, viewEvents.ViewLinesDeletedEvent]; + acceptVersionId(versionId: number): void; + + getViewLineCount(): number; + warmUpLookupCache(viewStartLineNumber: number, viewEndLineNumber: number): void; + getViewLineIndentGuide(viewLineNumber: number): number; + getViewLineContent(viewLineNumber: number): string; + getViewLineMinColumn(viewLineNumber: number): number; + getViewLineMaxColumn(viewLineNumber: number): number; + getViewLineData(viewLineNumber: number): ViewLineData; + getViewLinesData(viewStartLineNumber: number, viewEndLineNumber: number, needed: boolean[]): ViewLineData[]; +} + +export class CoordinatesConverter implements ICoordinatesConverter { + + private readonly _lines: SplitLinesCollection; + + constructor(lines: SplitLinesCollection) { + this._lines = lines; + } + + // View -> Model conversion and related methods + + public convertViewPositionToModelPosition(viewPosition: Position): Position { + return this._lines.convertViewPositionToModelPosition(viewPosition.lineNumber, viewPosition.column); + } + + public convertViewRangeToModelRange(viewRange: Range): Range { + let start = this._lines.convertViewPositionToModelPosition(viewRange.startLineNumber, viewRange.startColumn); + let end = this._lines.convertViewPositionToModelPosition(viewRange.endLineNumber, viewRange.endColumn); + return new Range(start.lineNumber, start.column, end.lineNumber, end.column); + } + + public convertViewSelectionToModelSelection(viewSelection: Selection): Selection { + let selectionStart = this._lines.convertViewPositionToModelPosition(viewSelection.selectionStartLineNumber, viewSelection.selectionStartColumn); + let position = this._lines.convertViewPositionToModelPosition(viewSelection.positionLineNumber, viewSelection.positionColumn); + return new Selection(selectionStart.lineNumber, selectionStart.column, position.lineNumber, position.column); + } + + public validateViewPosition(viewPosition: Position, expectedModelPosition: Position): Position { + return this._lines.validateViewPosition(viewPosition.lineNumber, viewPosition.column, expectedModelPosition); + } + + public validateViewRange(viewRange: Range, expectedModelRange: Range): Range { + var validViewStart = this._lines.validateViewPosition(viewRange.startLineNumber, viewRange.startColumn, expectedModelRange.getStartPosition()); + var validViewEnd = this._lines.validateViewPosition(viewRange.endLineNumber, viewRange.endColumn, expectedModelRange.getEndPosition()); + return new Range(validViewStart.lineNumber, validViewStart.column, validViewEnd.lineNumber, validViewEnd.column); + } + + // Model -> View conversion and related methods + + public convertModelPositionToViewPosition(modelPosition: Position): Position { + return this._lines.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column); + } + + public convertModelRangeToViewRange(modelRange: Range): Range { + let start = this._lines.convertModelPositionToViewPosition(modelRange.startLineNumber, modelRange.startColumn); + let end = this._lines.convertModelPositionToViewPosition(modelRange.endLineNumber, modelRange.endColumn); + return new Range(start.lineNumber, start.column, end.lineNumber, end.column); + } + + public convertModelSelectionToViewSelection(modelSelection: Selection): Selection { + let selectionStart = this._lines.convertModelPositionToViewPosition(modelSelection.selectionStartLineNumber, modelSelection.selectionStartColumn); + let position = this._lines.convertModelPositionToViewPosition(modelSelection.positionLineNumber, modelSelection.positionColumn); + return new Selection(selectionStart.lineNumber, selectionStart.column, position.lineNumber, position.column); + } + + public modelPositionIsVisible(modelPosition: Position): boolean { + return this._lines.modelPositionIsVisible(modelPosition.lineNumber, modelPosition.column); + } + +} + +export class SplitLinesCollection implements IViewModelLinesCollection { private model: editorCommon.IModel; private _validModelVersionId: number; @@ -91,6 +177,10 @@ export class SplitLinesCollection { this.hiddenAreasIds = this.model.deltaDecorations(this.hiddenAreasIds, []); } + public createCoordinatesConverter(): ICoordinatesConverter { + return new CoordinatesConverter(this); + } + private _ensureValidState(): void { let modelVersion = this.model.getVersionId(); if (modelVersion !== this._validModelVersionId) { diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index c05068d4a8379..56672b50f9aa5 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -8,13 +8,12 @@ import { EmitterEvent } from 'vs/base/common/eventEmitter'; import * as strings from 'vs/base/common/strings'; import { Position, IPosition } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; -import { Selection } from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { TokenizationRegistry, ColorId, LanguageId } from 'vs/editor/common/modes'; import { tokenizeLineToHTML } from 'vs/editor/common/modes/textToHtmlTokenizer'; import { ViewModelDecorations } from 'vs/editor/common/viewModel/viewModelDecorations'; import { MinimapLinesRenderingData, ViewLineRenderingData, ViewModelDecoration, IViewModel, ICoordinatesConverter, ViewEventsCollector } from 'vs/editor/common/viewModel/viewModel'; -import { SplitLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection'; +import { SplitLinesCollection, IViewModelLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { MinimapTokensColorTracker } from 'vs/editor/common/view/minimapCharRenderer'; import * as textModelEvents from 'vs/editor/common/model/textModelEvents'; @@ -22,72 +21,12 @@ import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOption import { CharacterHardWrappingLineMapperFactory } from 'vs/editor/common/viewModel/characterHardWrappingLineMapper'; import { ViewLayout } from 'vs/editor/common/viewLayout/viewLayout'; -export class CoordinatesConverter implements ICoordinatesConverter { - - private readonly _lines: SplitLinesCollection; - - constructor(lines: SplitLinesCollection) { - this._lines = lines; - } - - // View -> Model conversion and related methods - - public convertViewPositionToModelPosition(viewPosition: Position): Position { - return this._lines.convertViewPositionToModelPosition(viewPosition.lineNumber, viewPosition.column); - } - - public convertViewRangeToModelRange(viewRange: Range): Range { - let start = this._lines.convertViewPositionToModelPosition(viewRange.startLineNumber, viewRange.startColumn); - let end = this._lines.convertViewPositionToModelPosition(viewRange.endLineNumber, viewRange.endColumn); - return new Range(start.lineNumber, start.column, end.lineNumber, end.column); - } - - public convertViewSelectionToModelSelection(viewSelection: Selection): Selection { - let selectionStart = this._lines.convertViewPositionToModelPosition(viewSelection.selectionStartLineNumber, viewSelection.selectionStartColumn); - let position = this._lines.convertViewPositionToModelPosition(viewSelection.positionLineNumber, viewSelection.positionColumn); - return new Selection(selectionStart.lineNumber, selectionStart.column, position.lineNumber, position.column); - } - - public validateViewPosition(viewPosition: Position, expectedModelPosition: Position): Position { - return this._lines.validateViewPosition(viewPosition.lineNumber, viewPosition.column, expectedModelPosition); - } - - public validateViewRange(viewRange: Range, expectedModelRange: Range): Range { - var validViewStart = this._lines.validateViewPosition(viewRange.startLineNumber, viewRange.startColumn, expectedModelRange.getStartPosition()); - var validViewEnd = this._lines.validateViewPosition(viewRange.endLineNumber, viewRange.endColumn, expectedModelRange.getEndPosition()); - return new Range(validViewStart.lineNumber, validViewStart.column, validViewEnd.lineNumber, validViewEnd.column); - } - - // Model -> View conversion and related methods - - public convertModelPositionToViewPosition(modelPosition: Position): Position { - return this._lines.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column); - } - - public convertModelRangeToViewRange(modelRange: Range): Range { - let start = this._lines.convertModelPositionToViewPosition(modelRange.startLineNumber, modelRange.startColumn); - let end = this._lines.convertModelPositionToViewPosition(modelRange.endLineNumber, modelRange.endColumn); - return new Range(start.lineNumber, start.column, end.lineNumber, end.column); - } - - public convertModelSelectionToViewSelection(modelSelection: Selection): Selection { - let selectionStart = this._lines.convertModelPositionToViewPosition(modelSelection.selectionStartLineNumber, modelSelection.selectionStartColumn); - let position = this._lines.convertModelPositionToViewPosition(modelSelection.positionLineNumber, modelSelection.positionColumn); - return new Selection(selectionStart.lineNumber, selectionStart.column, position.lineNumber, position.column); - } - - public modelPositionIsVisible(modelPosition: Position): boolean { - return this._lines.modelPositionIsVisible(modelPosition.lineNumber, modelPosition.column); - } - -} - export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel { private readonly editorId: number; private readonly configuration: editorCommon.IConfiguration; private readonly model: editorCommon.IModel; - private readonly lines: SplitLinesCollection; + private readonly lines: IViewModelLinesCollection; public readonly coordinatesConverter: ICoordinatesConverter; public readonly viewLayout: ViewLayout; @@ -120,7 +59,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel conf.wrappingInfo.wrappingIndent ); - this.coordinatesConverter = new CoordinatesConverter(this.lines); + this.coordinatesConverter = this.lines.createCoordinatesConverter(); this.viewLayout = this._register(new ViewLayout(this.configuration, this.getLineCount()));