diff --git a/src/vs/editor/browser/view/viewController.ts b/src/vs/editor/browser/view/viewController.ts index 7c7310364b519b04cac3edaae163409291a7c17b..6019a1e47b85b71e0573f4be6f29a7afd27299cc 100644 --- a/src/vs/editor/browser/view/viewController.ts +++ b/src/vs/editor/browser/view/viewController.ts @@ -243,7 +243,7 @@ export class ViewController implements IViewController { // ---------------------- private convertViewToModelPosition(viewPosition: Position): Position { - return this.viewModel.convertViewPositionToModelPosition(viewPosition.lineNumber, viewPosition.column); + return this.viewModel.coordinatesConverter.convertViewPositionToModelPosition(viewPosition.lineNumber, viewPosition.column); } public emitKeyDown(e: IKeyboardEvent): void { diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts index 7d22a3512289ce54f095d87df9ec9b77ac2471f3..ba095705ca059c0c512aba7bd55deb6efd238adb 100644 --- a/src/vs/editor/browser/view/viewImpl.ts +++ b/src/vs/editor/browser/view/viewImpl.ts @@ -588,7 +588,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp lineNumber: modelLineNumber, column: modelColumn }); - let viewPosition = this._context.model.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column); + let viewPosition = this._context.model.coordinatesConverter.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column); return this.layoutProvider.getVerticalOffsetForLineNumber(viewPosition.lineNumber); }, delegateVerticalScrollbarMouseDown: (browserEvent: MouseEvent) => { @@ -605,7 +605,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp lineNumber: modelLineNumber, column: modelColumn }); - let viewPosition = this._context.model.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column); + let viewPosition = this._context.model.coordinatesConverter.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column); this._flushAccumulatedAndRenderNow(); let visibleRanges = this.viewLines.visibleRangesForRange2(new Range(viewPosition.lineNumber, viewPosition.column, viewPosition.lineNumber, viewPosition.column), 0); if (!visibleRanges) { @@ -641,7 +641,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp this._context.model.getLineMaxColumn(endLineNumber) ); - return this._context.model.convertViewRangeToModelRange(completelyVisibleLinesRange); + return this._context.model.coordinatesConverter.convertViewRangeToModelRange(completelyVisibleLinesRange); } public getInternalEventBus(): IEventEmitter { @@ -723,17 +723,16 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp } }; - let r: any = safeInvoke1Arg(callback, changeAccessor); + safeInvoke1Arg(callback, changeAccessor); // Invalidate changeAccessor changeAccessor.addZone = null; changeAccessor.removeZone = null; if (zonesHaveChanged) { + this.layoutProvider.onHeightMaybeChanged(); this._context.privateViewEventBus.emit(editorCommon.EventType.ViewZonesChanged, null); } - - return r; }); return zonesHaveChanged; } diff --git a/src/vs/editor/browser/view/viewOutgoingEvents.ts b/src/vs/editor/browser/view/viewOutgoingEvents.ts index 16ce702ebc58c6c06db82efc61f5e35b04366d8e..b18d165bf48c164c04fa52d80491e0246469c6df 100644 --- a/src/vs/editor/browser/view/viewOutgoingEvents.ts +++ b/src/vs/editor/browser/view/viewOutgoingEvents.ts @@ -99,11 +99,11 @@ export class ViewOutgoingEvents extends Disposable { } private _convertViewToModelPosition(viewPosition: Position): Position { - return this._viewModel.convertViewPositionToModelPosition(viewPosition.lineNumber, viewPosition.column); + return this._viewModel.coordinatesConverter.convertViewPositionToModelPosition(viewPosition.lineNumber, viewPosition.column); } private _convertViewToModelRange(viewRange: Range): Range { - return this._viewModel.convertViewRangeToModelRange(viewRange); + return this._viewModel.coordinatesConverter.convertViewRangeToModelRange(viewRange); } } diff --git a/src/vs/editor/browser/viewLayout/layoutProvider.ts b/src/vs/editor/browser/viewLayout/layoutProvider.ts index 196b663665a2ece45fec2b61a523e12c503e6e01..84d29c696718f7fc5ee25539a789501a0f948613 100644 --- a/src/vs/editor/browser/viewLayout/layoutProvider.ts +++ b/src/vs/editor/browser/viewLayout/layoutProvider.ts @@ -135,13 +135,12 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa this._configuration.setMaxLineNumber(this._model.getMaxLineNumber()); } - // ---- begin view event handlers - - public onZonesChanged(): boolean { + public onHeightMaybeChanged(): void { this._updateHeight(); - return false; } + // ---- begin view event handlers + public onModelFlushed(): boolean { this._linesLayout.onModelFlushed(this._model.getLineCount()); this._updateLineCount(); diff --git a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts index 898763b26bd565b00da113a7c99c7e11a34ccad4..e08a920da54c1fa68dffcea51678ab2643e4fcc4 100644 --- a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts +++ b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts @@ -328,12 +328,12 @@ export class ViewContentWidgets extends ViewPart { // Do not trust that widgets have a valid position let validModelPosition = this._context.model.validateModelPosition(widgetData.position); - if (!this._context.model.modelPositionIsVisible(validModelPosition)) { + if (!this._context.model.coordinatesConverter.modelPositionIsVisible(validModelPosition)) { // this position is hidden by the view model return null; } - let position = this._context.model.convertModelPositionToViewPosition(validModelPosition.lineNumber, validModelPosition.column); + let position = this._context.model.coordinatesConverter.convertModelPositionToViewPosition(validModelPosition.lineNumber, validModelPosition.column); let placement: IBoxLayoutResult = null; let fetchPlacement = () => { diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index 88f10de80a49a824733f970cbe6190f153e3437b..77d8ad65213ec0c25b10bfbe45fe2f0b7a12d5d8 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -300,7 +300,7 @@ export class ViewLines extends ViewLayer implements IViewLines { let nextLineModelLineNumber: number; if (includeNewLines) { - nextLineModelLineNumber = this._context.model.convertViewPositionToModelPosition(range.startLineNumber, 1).lineNumber; + nextLineModelLineNumber = this._context.model.coordinatesConverter.convertViewPositionToModelPosition(range.startLineNumber, 1).lineNumber; } let rendStartLineNumber = this._linesCollection.getStartLineNumber(); @@ -321,7 +321,7 @@ export class ViewLines extends ViewLayer implements IViewLines { if (includeNewLines && lineNumber < originalEndLineNumber) { let currentLineModelLineNumber = nextLineModelLineNumber; - nextLineModelLineNumber = this._context.model.convertViewPositionToModelPosition(lineNumber + 1, 1).lineNumber; + nextLineModelLineNumber = this._context.model.coordinatesConverter.convertViewPositionToModelPosition(lineNumber + 1, 1).lineNumber; if (currentLineModelLineNumber !== nextLineModelLineNumber) { visibleRangesForLine[visibleRangesForLine.length - 1].width += ViewLines.LINE_FEED_WIDTH; diff --git a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts index f4f1619f2dc199147b9a6a8f4a90ff45a44226dc..a7b9e2835e7cceb5aa48a98b1a1cb1f10d9b7cb9 100644 --- a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts +++ b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts @@ -178,8 +178,8 @@ export class ViewZones extends ViewPart { }); } - let viewPosition = this._context.model.convertModelPositionToViewPosition(zoneAfterModelPosition.lineNumber, zoneAfterModelPosition.column); - let isVisible = this._context.model.modelPositionIsVisible(zoneBeforeModelPosition); + let viewPosition = this._context.model.coordinatesConverter.convertModelPositionToViewPosition(zoneAfterModelPosition.lineNumber, zoneAfterModelPosition.column); + let isVisible = this._context.model.coordinatesConverter.modelPositionIsVisible(zoneBeforeModelPosition); return { afterViewLineNumber: viewPosition.lineNumber, heightInPx: (isVisible ? this._heightInPixels(zone) : 0) diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 862a801f08f0b57eaf372574a65b9c0f9483e218..207881635c7461624da632a23bbaea1805613d09 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -374,7 +374,6 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito public changeViewZones(callback: (accessor: editorBrowser.IViewZoneChangeAccessor) => void): void { if (!this.hasView) { - // console.warn('Cannot change view zones on editor that is not attached to a model, since there is no view.'); return; } let hasChanges = this._view.change(callback); diff --git a/src/vs/editor/common/commonCodeEditor.ts b/src/vs/editor/common/commonCodeEditor.ts index bb64dd98bb4f8f115e2d5f83ae296e91ddcfb3bd..f6cc57e12781132fb51bbc9fb02e6be2784716dd 100644 --- a/src/vs/editor/common/commonCodeEditor.ts +++ b/src/vs/editor/common/commonCodeEditor.ts @@ -815,28 +815,28 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom let viewModelHelper: IViewModelHelper = { viewModel: this.viewModel, getCurrentCompletelyVisibleViewLinesRangeInViewport: () => { - return this.viewModel.convertModelRangeToViewRange(this.getCompletelyVisibleLinesRangeInViewport()); + return this.viewModel.coordinatesConverter.convertModelRangeToViewRange(this.getCompletelyVisibleLinesRangeInViewport()); }, getCurrentCompletelyVisibleModelLinesRangeInViewport: () => { return this.getCompletelyVisibleLinesRangeInViewport(); }, convertModelPositionToViewPosition: (lineNumber: number, column: number) => { - return this.viewModel.convertModelPositionToViewPosition(lineNumber, column); + return this.viewModel.coordinatesConverter.convertModelPositionToViewPosition(lineNumber, column); }, convertModelRangeToViewRange: (modelRange: Range) => { - return this.viewModel.convertModelRangeToViewRange(modelRange); + return this.viewModel.coordinatesConverter.convertModelRangeToViewRange(modelRange); }, convertViewToModelPosition: (lineNumber: number, column: number) => { - return this.viewModel.convertViewPositionToModelPosition(lineNumber, column); + return this.viewModel.coordinatesConverter.convertViewPositionToModelPosition(lineNumber, column); }, - convertViewSelectionToModelSelection: (viewSelection: editorCommon.ISelection) => { - return this.viewModel.convertViewSelectionToModelSelection(viewSelection); + convertViewSelectionToModelSelection: (viewSelection: Selection) => { + return this.viewModel.coordinatesConverter.convertViewSelectionToModelSelection(viewSelection); }, validateViewPosition: (viewPosition: Position, modelPosition: Position): Position => { - return this.viewModel.validateViewPosition(viewPosition.lineNumber, viewPosition.column, modelPosition); + return this.viewModel.coordinatesConverter.validateViewPosition(viewPosition.lineNumber, viewPosition.column, modelPosition); }, validateViewRange: (viewRange: Range, modelRange: Range): Range => { - return this.viewModel.validateViewRange(viewRange.startLineNumber, viewRange.startColumn, viewRange.endLineNumber, viewRange.endColumn, modelRange); + return this.viewModel.coordinatesConverter.validateViewRange(viewRange.startLineNumber, viewRange.startColumn, viewRange.endLineNumber, viewRange.endColumn, modelRange); } }; diff --git a/src/vs/editor/common/controller/textAreaHandler.ts b/src/vs/editor/common/controller/textAreaHandler.ts index efabfc4e0a297c3da2de2cc882c457433c656f1e..66dea44eb672379c6dca73970ee2fa7f77e3b4de 100644 --- a/src/vs/editor/common/controller/textAreaHandler.ts +++ b/src/vs/editor/common/controller/textAreaHandler.ts @@ -352,7 +352,7 @@ export class TextAreaHandler extends Disposable { let range: Range = selections[0]; if (range.isEmpty()) { if (this.Browser.enableEmptySelectionClipboard) { - let modelLineNumber = this.model.convertViewPositionToModelPosition(range.startLineNumber, 1).lineNumber; + let modelLineNumber = this.model.coordinatesConverter.convertViewPositionToModelPosition(range.startLineNumber, 1).lineNumber; return this.model.getModelLineContent(modelLineNumber) + newLineCharacter; } else { return ''; diff --git a/src/vs/editor/common/controller/textAreaState.ts b/src/vs/editor/common/controller/textAreaState.ts index b12723009ea38021b885afb13f7aa0042503dfd6..1d73a1ebba545a8399a96423c56cbcd2270c80da 100644 --- a/src/vs/editor/common/controller/textAreaState.ts +++ b/src/vs/editor/common/controller/textAreaState.ts @@ -56,7 +56,10 @@ export interface ISimpleModel { getValueInRange(range: Range, eol: EndOfLinePreference): string; getModelLineContent(lineNumber: number): string; getLineCount(): number; - convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position; + + coordinatesConverter: { + convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position; + }; } export interface ITypeData { diff --git a/src/vs/editor/common/viewModel/viewModel.ts b/src/vs/editor/common/viewModel/viewModel.ts index dfca9baf93dc7c22797003908f5cc97919837fe2..dea2b2ff0692e249186ee1109eb7be93d135c91e 100644 --- a/src/vs/editor/common/viewModel/viewModel.ts +++ b/src/vs/editor/common/viewModel/viewModel.ts @@ -9,8 +9,27 @@ import { IModelDecoration, EndOfLinePreference, IPosition } from 'vs/editor/comm import { ViewLineToken } from 'vs/editor/common/core/viewLineToken'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; +import { Selection } from 'vs/editor/common/core/selection'; + +export interface ICoordinatesConverter { + // View -> Model conversion and related methods + convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position; + convertViewRangeToModelRange(viewRange: Range): Range; + convertViewSelectionToModelSelection(viewSelection: Selection): Selection; + validateViewPosition(viewLineNumber: number, viewColumn: number, expectedModelPosition: Position): Position; + validateViewRange(viewStartLineNumber: number, viewStartColumn: number, viewEndLineNumber: number, viewEndColumn: number, modelRange: Range): Range; + + // Model -> View conversion and related methods + convertModelPositionToViewPosition(modelLineNumber: number, modelColumn: number): Position; + convertModelRangeToViewRange(modelRange: Range): Range; + convertWholeLineModelRangeToViewRange(modelRange: Range): Range; + modelPositionIsVisible(position: Position): boolean; +} export interface IViewModel extends IEventEmitter { + + readonly coordinatesConverter: ICoordinatesConverter; + /** * Gives a hint that a lot of requests are about to come in for these line numbers. */ @@ -34,14 +53,9 @@ export interface IViewModel extends IEventEmitter { getEOL(): string; getValueInRange(range: Range, eol: EndOfLinePreference): string; - convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position; - convertViewRangeToModelRange(viewRange: Range): Range; - getModelLineContent(lineNumber: number): string; getModelLineMaxColumn(modelLineNumber: number): number; validateModelPosition(position: IPosition): Position; - convertModelPositionToViewPosition(modelLineNumber: number, modelColumn: number): Position; - modelPositionIsVisible(position: Position): boolean; } export class ViewLineRenderingData { diff --git a/src/vs/editor/common/viewModel/viewModelDecorations.ts b/src/vs/editor/common/viewModel/viewModelDecorations.ts index d35f67cf2256eea64337a17c4e49fdf51f58653c..84a97e452185cbe7d789c8ca0ae02f1b3359a87e 100644 --- a/src/vs/editor/common/viewModel/viewModelDecorations.ts +++ b/src/vs/editor/common/viewModel/viewModelDecorations.ts @@ -7,12 +7,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { Range } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { InlineDecoration, ViewModelDecoration } from 'vs/editor/common/viewModel/viewModel'; - -export interface IModelRangeToViewRangeConverter { - convertModelRangeToViewRange(modelRange: Range, isWholeLine: boolean): Range; - convertViewRangeToModelRange(viewRange: Range): Range; -} +import { InlineDecoration, ViewModelDecoration, ICoordinatesConverter } from 'vs/editor/common/viewModel/viewModel'; export interface IDecorationsViewportData { /** @@ -30,18 +25,18 @@ export class ViewModelDecorations implements IDisposable { private readonly editorId: number; private readonly model: editorCommon.IModel; private readonly configuration: editorCommon.IConfiguration; - private readonly converter: IModelRangeToViewRangeConverter; + private readonly _coordinatesConverter: ICoordinatesConverter; private _decorationsCache: { [decorationId: string]: ViewModelDecoration; }; private _cachedModelDecorationsResolver: IDecorationsViewportData; private _cachedModelDecorationsResolverViewRange: Range; - constructor(editorId: number, model: editorCommon.IModel, configuration: editorCommon.IConfiguration, converter: IModelRangeToViewRangeConverter) { + constructor(editorId: number, model: editorCommon.IModel, configuration: editorCommon.IConfiguration, coordinatesConverter: ICoordinatesConverter) { this.editorId = editorId; this.model = model; this.configuration = configuration; - this.converter = converter; + this._coordinatesConverter = coordinatesConverter; this._decorationsCache = Object.create(null); this._clearCachedModelDecorationsResolver(); @@ -99,7 +94,11 @@ export class ViewModelDecorations implements IDisposable { this._decorationsCache[id] = r; } if (r.range === null) { - r.range = this.converter.convertModelRangeToViewRange(modelDecoration.range, modelDecoration.options.isWholeLine); + if (modelDecoration.options.isWholeLine) { + r.range = this._coordinatesConverter.convertWholeLineModelRangeToViewRange(modelDecoration.range); + } else { + r.range = this._coordinatesConverter.convertModelRangeToViewRange(modelDecoration.range); + } } return r; } @@ -133,7 +132,7 @@ export class ViewModelDecorations implements IDisposable { } private _getDecorationsViewportData(viewportRange: Range): IDecorationsViewportData { - let viewportModelRange = this.converter.convertViewRangeToModelRange(viewportRange); + let viewportModelRange = this._coordinatesConverter.convertViewRangeToModelRange(viewportRange); let startLineNumber = viewportRange.startLineNumber; let endLineNumber = viewportRange.endLineNumber; let modelDecorations = this.model.getDecorationsInRange(viewportModelRange, this.editorId, this.configuration.editor.readOnly); diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index d16594597ad6199790c9268db88a60508d7e3acc..ed8255943079f99731a37a50c1b09bede02f4625 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -13,20 +13,83 @@ import { Selection } from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { ViewModelCursors } from 'vs/editor/common/viewModel/viewModelCursors'; import { ViewModelDecorations } from 'vs/editor/common/viewModel/viewModelDecorations'; -import { ViewLineRenderingData, ViewModelDecoration, IViewModel } from 'vs/editor/common/viewModel/viewModel'; +import { ViewLineRenderingData, ViewModelDecoration, IViewModel, ICoordinatesConverter } from 'vs/editor/common/viewModel/viewModel'; import { SplitLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection'; +export class CoordinatesConverter implements ICoordinatesConverter { + + private readonly _model: editorCommon.IModel; + private readonly _lines: SplitLinesCollection; + + constructor(model: editorCommon.IModel, lines: SplitLinesCollection) { + this._model = model; + this._lines = lines; + } + + // View -> Model conversion and related methods + + public convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position { + return this._lines.convertViewPositionToModelPosition(viewLineNumber, viewColumn); + } + + 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(viewLineNumber: number, viewColumn: number, expectedModelPosition: Position): Position { + return this._lines.validateViewPosition(viewLineNumber, viewColumn, expectedModelPosition); + } + + public validateViewRange(viewStartLineNumber: number, viewStartColumn: number, viewEndLineNumber: number, viewEndColumn: number, modelRange: Range): Range { + var validViewStart = this.validateViewPosition(viewStartLineNumber, viewStartColumn, modelRange.getStartPosition()); + var validViewEnd = this.validateViewPosition(viewEndLineNumber, viewEndColumn, modelRange.getEndPosition()); + return new Range(validViewStart.lineNumber, validViewStart.column, validViewEnd.lineNumber, validViewEnd.column); + } + + // Model -> View conversion and related methods + + public convertModelPositionToViewPosition(modelLineNumber: number, modelColumn: number): Position { + return this._lines.convertModelPositionToViewPosition(modelLineNumber, modelColumn); + } + + 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 convertWholeLineModelRangeToViewRange(modelRange: Range): Range { + let start = this._lines.convertModelPositionToViewPosition(modelRange.startLineNumber, 1); + let end = this._lines.convertModelPositionToViewPosition(modelRange.endLineNumber, this._model.getLineMaxColumn(modelRange.endLineNumber)); + return new Range(start.lineNumber, start.column, end.lineNumber, end.column); + } + + public modelPositionIsVisible(position: Position): boolean { + return this._lines.modelPositionIsVisible(position.lineNumber, position.column); + } + +} + export class ViewModel extends EventEmitter implements IViewModel { - private editorId: number; - private configuration: editorCommon.IConfiguration; - private model: editorCommon.IModel; + private readonly lines: SplitLinesCollection; + private readonly editorId: number; + private readonly configuration: editorCommon.IConfiguration; + private readonly model: editorCommon.IModel; + public readonly coordinatesConverter: ICoordinatesConverter; private listenersToRemove: IDisposable[]; private _toDispose: IDisposable[]; - private lines: SplitLinesCollection; - private decorations: ViewModelDecorations; - private cursors: ViewModelCursors; + private readonly decorations: ViewModelDecorations; + private readonly cursors: ViewModelCursors; private _renderCustomLineNumbers: (lineNumber: number) => string; private _renderRelativeLineNumbers: boolean; @@ -42,23 +105,15 @@ export class ViewModel extends EventEmitter implements IViewModel { this.configuration = configuration; this.model = model; + this.coordinatesConverter = new CoordinatesConverter(this.model, this.lines); + this._lastCursorPosition = new Position(1, 1); this._renderCustomLineNumbers = this.configuration.editor.viewInfo.renderCustomLineNumbers; this._renderRelativeLineNumbers = this.configuration.editor.viewInfo.renderRelativeLineNumbers; this._centeredViewLine = -1; - this.decorations = new ViewModelDecorations(this.editorId, this.model, this.configuration, { - convertModelRangeToViewRange: (modelRange: Range, isWholeLine: boolean): Range => { - if (isWholeLine) { - return this.convertWholeLineModelRangeToViewRange(modelRange); - } - return this.convertModelRangeToViewRange(modelRange); - }, - convertViewRangeToModelRange: (viewRange: Range): Range => { - return this.convertViewRangeToModelRange(viewRange); - } - }); + this.decorations = new ViewModelDecorations(this.editorId, this.model, this.configuration, this.coordinatesConverter); this.decorations.reset(); this.cursors = new ViewModelCursors(this.configuration); @@ -93,11 +148,7 @@ export class ViewModel extends EventEmitter implements IViewModel { this.listenersToRemove = dispose(this.listenersToRemove); this._toDispose = dispose(this._toDispose); this.decorations.dispose(); - this.decorations = null; this.lines.dispose(); - this.lines = null; - this.configuration = null; - this.model = null; } private _onTabSizeChange(newTabSize: number): boolean { @@ -122,7 +173,7 @@ export class ViewModel extends EventEmitter implements IViewModel { private _restoreCenteredModelRange(range: Range): void { // modelLine -> viewLine - var newCenteredViewRange = this.convertModelRangeToViewRange(range); + var newCenteredViewRange = this.coordinatesConverter.convertModelRangeToViewRange(range); // Send a reveal event to restore the centered content var restoreRevealEvent: editorCommon.IViewRevealRangeEvent = { @@ -187,7 +238,7 @@ export class ViewModel extends EventEmitter implements IViewModel { } let viewLineNumber = this._centeredViewLine; let currentCenteredViewRange = new Range(viewLineNumber, this.getLineMinColumn(viewLineNumber), viewLineNumber, this.getLineMaxColumn(viewLineNumber)); - return this.convertViewRangeToModelRange(currentCenteredViewRange); + return this.coordinatesConverter.convertViewRangeToModelRange(currentCenteredViewRange); } private _onEvents(events: EmitterEvent[]): void { @@ -346,8 +397,8 @@ export class ViewModel extends EventEmitter implements IViewModel { for (let i = 0, len = e.ranges.length; i < len; i++) { let modelRange = e.ranges[i]; - let viewStartLineNumber = this.convertModelPositionToViewPosition(modelRange.fromLineNumber, 1).lineNumber; - let viewEndLineNumber = this.convertModelPositionToViewPosition(modelRange.toLineNumber, this.model.getLineMaxColumn(modelRange.toLineNumber)).lineNumber; + let viewStartLineNumber = this.coordinatesConverter.convertModelPositionToViewPosition(modelRange.fromLineNumber, 1).lineNumber; + let viewEndLineNumber = this.coordinatesConverter.convertModelPositionToViewPosition(modelRange.toLineNumber, this.model.getLineMaxColumn(modelRange.toLineNumber)).lineNumber; viewRanges[i] = { fromLineNumber: viewStartLineNumber, toLineNumber: viewEndLineNumber @@ -367,16 +418,6 @@ export class ViewModel extends EventEmitter implements IViewModel { this.lines.onModelLinesInserted(e.versionId, e.fromLineNumber, e.toLineNumber, e.detail.split('\n'), (eventType: string, payload: any) => this.emit(eventType, payload)); } - public validateViewRange(viewStartLineNumber: number, viewStartColumn: number, viewEndLineNumber: number, viewEndColumn: number, modelRange: Range): Range { - var validViewStart = this.validateViewPosition(viewStartLineNumber, viewStartColumn, modelRange.getStartPosition()); - var validViewEnd = this.validateViewPosition(viewEndLineNumber, viewEndColumn, modelRange.getEndPosition()); - return new Range(validViewStart.lineNumber, validViewStart.column, validViewEnd.lineNumber, validViewEnd.column); - } - - public validateViewPosition(viewLineNumber: number, viewColumn: number, expectedModelPosition: Position): Position { - return this.lines.validateViewPosition(viewLineNumber, viewColumn, expectedModelPosition); - } - private onCursorPositionChanged(e: editorCommon.ICursorPositionChangedEvent): void { this.cursors.onCursorPositionChanged(e, (eventType: string, payload: any) => this.emit(eventType, payload)); } @@ -388,7 +429,7 @@ export class ViewModel extends EventEmitter implements IViewModel { if (!e.viewRange) { e = { range: e.range, - viewRange: this.convertModelRangeToViewRange(e.range), + viewRange: this.coordinatesConverter.convertModelRangeToViewRange(e.range), verticalType: e.verticalType, revealHorizontal: e.revealHorizontal, revealCursor: e.revealCursor, @@ -450,7 +491,7 @@ export class ViewModel extends EventEmitter implements IViewModel { } public getLineRenderLineNumber(viewLineNumber: number): string { - let modelPosition = this.convertViewPositionToModelPosition(viewLineNumber, 1); + let modelPosition = this.coordinatesConverter.convertViewPositionToModelPosition(viewLineNumber, 1); if (modelPosition.column !== 1) { return ''; } @@ -509,30 +550,10 @@ export class ViewModel extends EventEmitter implements IViewModel { } public getValueInRange(range: Range, eol: editorCommon.EndOfLinePreference): string { - var modelRange = this.convertViewRangeToModelRange(range); + var modelRange = this.coordinatesConverter.convertViewRangeToModelRange(range); return this.model.getValueInRange(modelRange, eol); } - // View -> Model conversion and related methods - - public convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position { - return this.lines.convertViewPositionToModelPosition(viewLineNumber, viewColumn); - } - - public convertViewRangeToModelRange(viewRange: Range): Range { - var start = this.convertViewPositionToModelPosition(viewRange.startLineNumber, viewRange.startColumn); - var end = this.convertViewPositionToModelPosition(viewRange.endLineNumber, viewRange.endColumn); - return new Range(start.lineNumber, start.column, end.lineNumber, end.column); - } - - public convertViewSelectionToModelSelection(viewSelection: editorCommon.ISelection): Selection { - let selectionStart = this.convertViewPositionToModelPosition(viewSelection.selectionStartLineNumber, viewSelection.selectionStartColumn); - let position = this.convertViewPositionToModelPosition(viewSelection.positionLineNumber, viewSelection.positionColumn); - return new Selection(selectionStart.lineNumber, selectionStart.column, position.lineNumber, position.column); - } - - // Model -> View conversion and related methods - public getModelLineContent(modelLineNumber: number): string { return this.model.getLineContent(modelLineNumber); } @@ -544,25 +565,4 @@ export class ViewModel extends EventEmitter implements IViewModel { public validateModelPosition(position: editorCommon.IPosition): Position { return this.model.validatePosition(position); } - - public convertModelPositionToViewPosition(modelLineNumber: number, modelColumn: number): Position { - return this.lines.convertModelPositionToViewPosition(modelLineNumber, modelColumn); - } - - public convertModelRangeToViewRange(modelRange: Range): Range { - var start = this.convertModelPositionToViewPosition(modelRange.startLineNumber, modelRange.startColumn); - var end = this.convertModelPositionToViewPosition(modelRange.endLineNumber, modelRange.endColumn); - return new Range(start.lineNumber, start.column, end.lineNumber, end.column); - } - - public convertWholeLineModelRangeToViewRange(modelRange: Range): Range { - var start = this.convertModelPositionToViewPosition(modelRange.startLineNumber, 1); - var end = this.convertModelPositionToViewPosition(modelRange.endLineNumber, this.model.getLineMaxColumn(modelRange.endLineNumber)); - return new Range(start.lineNumber, start.column, end.lineNumber, end.column); - } - - public modelPositionIsVisible(position: Position): boolean { - return this.lines.modelPositionIsVisible(position.lineNumber, position.column); - } - -} \ No newline at end of file +} diff --git a/src/vs/editor/test/browser/controller/imeTester.ts b/src/vs/editor/test/browser/controller/imeTester.ts index 2abbab025a613e146389f975b4cd67d7183d57a9..367462696c0539a565fd4cbb29d57e0910c618f7 100644 --- a/src/vs/editor/test/browser/controller/imeTester.ts +++ b/src/vs/editor/test/browser/controller/imeTester.ts @@ -19,6 +19,12 @@ class SingleLineTestModel implements ISimpleModel { private _line: string; private _eol: string; + public coordinatesConverter = { + convertViewPositionToModelPosition: (viewLineNumber: number, viewColumn: number): Position => { + return new Position(viewLineNumber, viewColumn); + } + }; + constructor(line: string) { this._line = line; this._eol = '\n'; @@ -47,10 +53,6 @@ class SingleLineTestModel implements ISimpleModel { getLineCount(): number { return 1; } - - convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position { - return new Position(viewLineNumber, viewColumn); - } } class TestView { diff --git a/src/vs/editor/test/common/controller/textAreaState.test.ts b/src/vs/editor/test/common/controller/textAreaState.test.ts index 0923b59d118b598f123da1111ee4a71857bde883..a8c022c68c944ef951d16f5f75a2d22b36c5a921 100644 --- a/src/vs/editor/test/common/controller/textAreaState.test.ts +++ b/src/vs/editor/test/common/controller/textAreaState.test.ts @@ -411,6 +411,12 @@ class SimpleModel implements ISimpleModel { private _lines: string[]; private _eol: string; + public coordinatesConverter = { + convertViewPositionToModelPosition: (viewLineNumber: number, viewColumn: number): Position => { + return new Position(viewLineNumber, viewColumn); + } + }; + constructor(lines: string[], eol: string) { this._lines = lines; this._eol = eol; @@ -466,8 +472,4 @@ class SimpleModel implements ISimpleModel { public getLineCount(): number { return this._lines.length; } - - public convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position { - return new Position(viewLineNumber, viewColumn); - } }