提交 15627c74 编写于 作者: A Alex Dima

View improvements:

 - add a prefix sum cache that is warmed up for the viewport
 - improve some of the position mapping/validation code
上级 cf67c68b
......@@ -58,7 +58,6 @@ export interface IView extends IDisposable {
createOverviewRuler(cssClassName: string, minimumHeight: number, maximumHeight: number): IOverviewRuler;
getCodeEditorHelper(): ICodeEditorHelper;
getCenteredRangeInViewport(): Range;
/**
* Returns the range of lines in the view port which are completely visible.
*/
......
......@@ -852,20 +852,6 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
return result;
}
private _lastRenderedCenteredLineNumber: number = -1;
public getCenteredRangeInViewport(): Range {
if (this._isDisposed) {
throw new Error('ViewImpl.getCenteredRangeInViewport: View is disposed');
}
if (this._lastRenderedCenteredLineNumber === -1) {
return null;
}
let viewLineNumber = this._lastRenderedCenteredLineNumber;
let currentCenteredViewRange = new Range(viewLineNumber, this._context.model.getLineMinColumn(viewLineNumber), viewLineNumber, this._context.model.getLineMaxColumn(viewLineNumber));
return this._context.model.convertViewRangeToModelRange(currentCenteredViewRange);
}
private _actualRender(): void {
if (!dom.isInDOM(this.domNode)) {
return;
......@@ -880,7 +866,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
}
let partialViewportData = this.layoutProvider.getLinesViewportData();
this._lastRenderedCenteredLineNumber = partialViewportData.centeredLineNumber;
this._context.model.setViewport(partialViewportData.startLineNumber, partialViewportData.endLineNumber, partialViewportData.centeredLineNumber);
let viewportData = new ViewportData(partialViewportData, this._context.model);
......
......@@ -151,7 +151,7 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito
if (!this.hasView) {
return null;
}
return this._view.getCenteredRangeInViewport();
return this.viewModel.getCenteredRangeInViewport();
}
public getCompletelyVisibleLinesRangeInViewport(): Range {
......
......@@ -809,8 +809,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom
linesCollection,
this.id,
this._configuration,
this.model,
() => this.getCenteredRangeInViewport()
this.model
);
let viewModelHelper: IViewModelHelper = {
......
......@@ -46,14 +46,14 @@ export class PrefixSumComputer {
return this.values.length;
}
public insertValues(insertIndex: number, insertValues: Uint32Array): void {
public insertValues(insertIndex: number, insertValues: Uint32Array): boolean {
insertIndex = toUint32(insertIndex);
const oldValues = this.values;
const oldPrefixSum = this.prefixSum;
const insertValuesLen = insertValues.length;
if (insertValuesLen === 0) {
return;
return false;
}
this.values = new Uint32Array(oldValues.length + insertValuesLen);
......@@ -69,22 +69,24 @@ export class PrefixSumComputer {
if (this.prefixSumValidIndex[0] >= 0) {
this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));
}
return true;
}
public changeValue(index: number, value: number): void {
public changeValue(index: number, value: number): boolean {
index = toUint32(index);
value = toUint32(value);
if (this.values[index] === value) {
return;
return false;
}
this.values[index] = value;
if (index - 1 < this.prefixSumValidIndex[0]) {
this.prefixSumValidIndex[0] = index - 1;
}
return true;
}
public removeValues(startIndex: number, cnt: number): void {
public removeValues(startIndex: number, cnt: number): boolean {
startIndex = toUint32(startIndex);
cnt = toUint32(cnt);
......@@ -92,7 +94,7 @@ export class PrefixSumComputer {
const oldPrefixSum = this.prefixSum;
if (startIndex >= oldValues.length) {
return;
return false;
}
let maxCnt = oldValues.length - startIndex;
......@@ -101,7 +103,7 @@ export class PrefixSumComputer {
}
if (cnt === 0) {
return;
return false;
}
this.values = new Uint32Array(oldValues.length - cnt);
......@@ -115,6 +117,7 @@ export class PrefixSumComputer {
if (this.prefixSumValidIndex[0] >= 0) {
this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));
}
return true;
}
public getTotalValue(): number {
......@@ -185,3 +188,77 @@ export class PrefixSumComputer {
return new PrefixSumIndexOfResult(mid, accumulatedValue - midStart);
}
}
export class PrefixSumComputerWithCache {
private readonly _actual: PrefixSumComputer;
private _cacheAccumulatedValueStart: number = 0;
private _cache: PrefixSumIndexOfResult[] = null;
constructor(values: Uint32Array) {
this._actual = new PrefixSumComputer(values);
this._bustCache();
}
private _bustCache(): void {
this._cacheAccumulatedValueStart = 0;
this._cache = null;
}
public getCount(): number {
return this._actual.getCount();
}
public insertValues(insertIndex: number, insertValues: Uint32Array): void {
if (this._actual.insertValues(insertIndex, insertValues)) {
this._bustCache();
}
}
public changeValue(index: number, value: number): void {
if (this._actual.changeValue(index, value)) {
this._bustCache();
}
}
public removeValues(startIndex: number, cnt: number): void {
if (this._actual.removeValues(startIndex, cnt)) {
this._bustCache();
}
}
public getTotalValue(): number {
return this._actual.getTotalValue();
}
public getAccumulatedValue(index: number): number {
return this._actual.getAccumulatedValue(index);
}
public getIndexOf(accumulatedValue: number): PrefixSumIndexOfResult {
accumulatedValue = Math.floor(accumulatedValue); //@perf
if (this._cache !== null) {
let cacheIndex = accumulatedValue - this._cacheAccumulatedValueStart;
if (cacheIndex >= 0 && cacheIndex < this._cache.length) {
// Cache hit!
return this._cache[cacheIndex];
}
}
// Cache miss!
return this._actual.getIndexOf(accumulatedValue);
}
/**
* Gives a hint that a lot of requests are about to come in for these accumulated values.
*/
public warmUpCache(accumulatedValueStart: number, accumulatedValueEnd: number): void {
let newCache: PrefixSumIndexOfResult[] = [];
for (let accumulatedValue = accumulatedValueStart; accumulatedValue <= accumulatedValueEnd; accumulatedValue++) {
newCache[accumulatedValue - accumulatedValueStart] = this.getIndexOf(accumulatedValue);
}
this._cache = newCache;
this._cacheAccumulatedValueStart = accumulatedValueStart;
}
}
......@@ -11,6 +11,11 @@ import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
export interface IViewModel extends IEventEmitter {
/**
* Gives a hint that a lot of requests are about to come in for these line numbers.
*/
setViewport(startLineNumber: number, endLineNumber: number, centeredLineNumber: number): void;
getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];
getViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;
......
......@@ -4,66 +4,45 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
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 { Position } from 'vs/editor/common/core/position';
export interface IConverter {
validateViewPosition(viewLineNumber: number, viewColumn: number, modelPosition: Position): Position;
validateViewSelection(viewSelection: Selection, modelSelection: Selection): Selection;
convertModelSelectionToViewSelection(modelSelection: Selection): Selection;
convertModelRangeToViewRange(modelRange: Range): Range;
}
export class ViewModelCursors {
private configuration: editorCommon.IConfiguration;
private converter: IConverter;
private readonly configuration: editorCommon.IConfiguration;
private lastCursorPositionChangedEvent: editorCommon.ICursorPositionChangedEvent;
private lastCursorSelectionChangedEvent: editorCommon.ICursorSelectionChangedEvent;
constructor(configuration: editorCommon.IConfiguration, converter: IConverter) {
constructor(configuration: editorCommon.IConfiguration) {
this.configuration = configuration;
this.converter = converter;
this.lastCursorPositionChangedEvent = null;
this.lastCursorSelectionChangedEvent = null;
}
public getSelections(): Selection[] {
if (this.lastCursorSelectionChangedEvent) {
var selections: Selection[] = [];
selections.push(this.converter.convertModelSelectionToViewSelection(this.lastCursorSelectionChangedEvent.selection));
for (var i = 0, len = this.lastCursorSelectionChangedEvent.secondarySelections.length; i < len; i++) {
selections.push(this.converter.convertModelSelectionToViewSelection(this.lastCursorSelectionChangedEvent.secondarySelections[i]));
}
return selections;
} else {
return [new Selection(1, 1, 1, 1)];
/**
* Limit position to be somewhere where it can actually be rendered
*/
private static _toPositionThatCanBeRendered(position: Position, stopRenderingLineAfter: number) {
// Limit position to be somewhere where it can actually be rendered
if (stopRenderingLineAfter !== -1 && position.column > stopRenderingLineAfter) {
position = new Position(position.lineNumber, stopRenderingLineAfter);
}
return position;
}
public onCursorPositionChanged(e: editorCommon.ICursorPositionChangedEvent, emit: (eventType: string, payload: any) => void): void {
this.lastCursorPositionChangedEvent = e;
var position = this.converter.validateViewPosition(e.viewPosition.lineNumber, e.viewPosition.column, e.position),
stopRenderingLineAfter = this.configuration.editor.viewInfo.stopRenderingLineAfter;
const stopRenderingLineAfter = this.configuration.editor.viewInfo.stopRenderingLineAfter;
// Limit position to be somewhere where it can actually be rendered
if (stopRenderingLineAfter !== -1 && position.column > stopRenderingLineAfter) {
position = new Position(position.lineNumber, stopRenderingLineAfter);
}
var secondaryPositions: Position[] = [];
for (var i = 0, len = e.secondaryPositions.length; i < len; i++) {
secondaryPositions[i] = this.converter.validateViewPosition(e.secondaryViewPositions[i].lineNumber, e.secondaryViewPositions[i].column, e.secondaryPositions[i]);
// Limit position to be somewhere where it can actually be rendered
if (stopRenderingLineAfter !== -1 && secondaryPositions[i].column > stopRenderingLineAfter) {
secondaryPositions[i] = new Position(secondaryPositions[i].lineNumber, stopRenderingLineAfter);
}
let position = ViewModelCursors._toPositionThatCanBeRendered(e.viewPosition, stopRenderingLineAfter);
let secondaryPositions: Position[] = [];
for (let i = 0, len = e.secondaryPositions.length; i < len; i++) {
secondaryPositions[i] = ViewModelCursors._toPositionThatCanBeRendered(e.secondaryViewPositions[i], stopRenderingLineAfter);
}
var newEvent: editorCommon.IViewCursorPositionChangedEvent = {
let newEvent: editorCommon.IViewCursorPositionChangedEvent = {
position: position,
secondaryPositions: secondaryPositions,
isInEditableRange: e.isInEditableRange
......@@ -74,31 +53,16 @@ export class ViewModelCursors {
public onCursorSelectionChanged(e: editorCommon.ICursorSelectionChangedEvent, emit: (eventType: string, payload: any) => void): void {
this.lastCursorSelectionChangedEvent = e;
let selection = this.converter.validateViewSelection(e.viewSelection, e.selection);
let secondarySelections: Selection[] = [];
for (let i = 0, len = e.secondarySelections.length; i < len; i++) {
secondarySelections[i] = this.converter.validateViewSelection(e.secondaryViewSelections[i], e.secondarySelections[i]);
}
let newEvent: editorCommon.IViewCursorSelectionChangedEvent = {
selection: selection,
secondarySelections: secondarySelections
selection: e.viewSelection,
secondarySelections: e.secondaryViewSelections
};
emit(editorCommon.ViewEventNames.CursorSelectionChangedEvent, newEvent);
}
public onCursorRevealRange(e: editorCommon.ICursorRevealRangeEvent, emit: (eventType: string, payload: any) => void): void {
var viewRange: Range = null;
if (e.viewRange) {
var viewStartRange = this.converter.validateViewPosition(e.viewRange.startLineNumber, e.viewRange.startColumn, e.range.getStartPosition());
var viewEndRange = this.converter.validateViewPosition(e.viewRange.endLineNumber, e.viewRange.endColumn, e.range.getEndPosition());
viewRange = new Range(viewStartRange.lineNumber, viewStartRange.column, viewEndRange.lineNumber, viewEndRange.column);
} else {
viewRange = this.converter.convertModelRangeToViewRange(e.range);
}
var newEvent: editorCommon.IViewRevealRangeEvent = {
range: viewRange,
let newEvent: editorCommon.IViewRevealRangeEvent = {
range: e.viewRange,
verticalType: e.verticalType,
revealHorizontal: e.revealHorizontal,
revealCursor: e.revealCursor
......@@ -107,7 +71,7 @@ export class ViewModelCursors {
}
public onCursorScrollRequest(e: editorCommon.ICursorScrollRequestEvent, emit: (eventType: string, payload: any) => void): void {
var newEvent: editorCommon.IViewScrollRequestEvent = {
let newEvent: editorCommon.IViewScrollRequestEvent = {
deltaLines: e.deltaLines,
revealCursor: e.revealCursor
};
......@@ -122,5 +86,4 @@ export class ViewModelCursors {
this.onCursorSelectionChanged(this.lastCursorSelectionChangedEvent, emit);
}
}
}
\ No newline at end of file
}
......@@ -32,9 +32,9 @@ export class ViewModel extends EventEmitter implements IViewModel {
private _renderRelativeLineNumbers: boolean;
private _lastCursorPosition: Position;
private getCurrentCenteredModelRange: () => Range;
private _centeredViewLine: number;
constructor(lines: SplitLinesCollection, editorId: number, configuration: editorCommon.IConfiguration, model: editorCommon.IModel, getCurrentCenteredModelRange: () => Range) {
constructor(lines: SplitLinesCollection, editorId: number, configuration: editorCommon.IConfiguration, model: editorCommon.IModel) {
super();
this.lines = lines;
......@@ -46,7 +46,7 @@ export class ViewModel extends EventEmitter implements IViewModel {
this._renderCustomLineNumbers = this.configuration.editor.viewInfo.renderCustomLineNumbers;
this._renderRelativeLineNumbers = this.configuration.editor.viewInfo.renderRelativeLineNumbers;
this.getCurrentCenteredModelRange = getCurrentCenteredModelRange;
this._centeredViewLine = -1;
this.decorations = new ViewModelDecorations(this.editorId, this.model, this.configuration, {
convertModelRangeToViewRange: (modelRange: Range, isWholeLine: boolean): Range => {
......@@ -61,7 +61,7 @@ export class ViewModel extends EventEmitter implements IViewModel {
});
this.decorations.reset();
this.cursors = new ViewModelCursors(this.configuration, this);
this.cursors = new ViewModelCursors(this.configuration);
this.listenersToRemove = [];
this._toDispose = [];
......@@ -180,6 +180,16 @@ export class ViewModel extends EventEmitter implements IViewModel {
return false;
}
public getCenteredRangeInViewport(): Range {
if (this._centeredViewLine === -1) {
// Never got rendered
return null;
}
let viewLineNumber = this._centeredViewLine;
let currentCenteredViewRange = new Range(viewLineNumber, this.getLineMinColumn(viewLineNumber), viewLineNumber, this.getLineMaxColumn(viewLineNumber));
return this.convertViewRangeToModelRange(currentCenteredViewRange);
}
private _onEvents(events: EmitterEvent[]): void {
// We might need to restore the current centered view range in the following circumstances:
......@@ -193,7 +203,7 @@ export class ViewModel extends EventEmitter implements IViewModel {
let previousCenteredModelRange: Range = null;
if (!ViewModel._containsModelContentChangeEvent(events) && ViewModel._containsWrappingRelatedEvents(events)) {
previousCenteredModelRange = this.getCurrentCenteredModelRange();
previousCenteredModelRange = this.getCenteredRangeInViewport();
}
let i: number,
......@@ -254,9 +264,9 @@ export class ViewModel extends EventEmitter implements IViewModel {
case editorCommon.EventType.ModelOptionsChanged:
// A tab size change causes a line mapping changed event => all view parts will repaint OK, no further event needed here
let prevLineCount = this.lines.getOutputLineCount();
let prevLineCount = this.lines.getViewLineCount();
let tabSizeChanged = this._onTabSizeChange(this.model.getOptions().tabSize);
let newLineCount = this.lines.getOutputLineCount();
let newLineCount = this.lines.getViewLineCount();
if (tabSizeChanged && prevLineCount !== newLineCount) {
revealPreviousCenteredModelRange = true;
}
......@@ -363,37 +373,8 @@ export class ViewModel extends EventEmitter implements IViewModel {
return new Range(validViewStart.lineNumber, validViewStart.column, validViewEnd.lineNumber, validViewEnd.column);
}
public validateViewPosition(viewLineNumber: number, viewColumn: number, modelPosition: Position): Position {
if (viewLineNumber < 1) {
viewLineNumber = 1;
}
var lineCount = this.getLineCount();
if (viewLineNumber > lineCount) {
viewLineNumber = lineCount;
}
var viewMinColumn = this.getLineMinColumn(viewLineNumber);
var viewMaxColumn = this.getLineMaxColumn(viewLineNumber);
if (viewColumn < viewMinColumn) {
viewColumn = viewMinColumn;
}
if (viewColumn > viewMaxColumn) {
viewColumn = viewMaxColumn;
}
var computedModelPosition = this.convertViewPositionToModelPosition(viewLineNumber, viewColumn);
if (computedModelPosition.equals(modelPosition)) {
return new Position(viewLineNumber, viewColumn);
}
return this.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column);
}
public validateViewSelection(viewSelection: Selection, modelSelection: Selection): Selection {
let modelSelectionStart = new Position(modelSelection.selectionStartLineNumber, modelSelection.selectionStartColumn);
let modelPosition = new Position(modelSelection.positionLineNumber, modelSelection.positionColumn);
let viewSelectionStart = this.validateViewPosition(viewSelection.selectionStartLineNumber, viewSelection.selectionStartColumn, modelSelectionStart);
let viewPosition = this.validateViewPosition(viewSelection.positionLineNumber, viewSelection.positionColumn, modelPosition);
return new Selection(viewSelectionStart.lineNumber, viewSelectionStart.column, viewPosition.lineNumber, viewPosition.column);
public validateViewPosition(viewLineNumber: number, viewColumn: number, expectedModelPosition: Position): Position {
return this.lines.validateViewPosition(viewLineNumber, viewColumn, expectedModelPosition);
}
private onCursorPositionChanged(e: editorCommon.ICursorPositionChangedEvent): void {
......@@ -403,6 +384,16 @@ export class ViewModel extends EventEmitter implements IViewModel {
this.cursors.onCursorSelectionChanged(e, (eventType: string, payload: any) => this.emit(eventType, payload));
}
private onCursorRevealRange(e: editorCommon.ICursorRevealRangeEvent): void {
// Ensure event has viewRange
if (!e.viewRange) {
e = {
range: e.range,
viewRange: this.convertModelRangeToViewRange(e.range),
verticalType: e.verticalType,
revealHorizontal: e.revealHorizontal,
revealCursor: e.revealCursor,
};
}
this.cursors.onCursorRevealRange(e, (eventType: string, payload: any) => this.emit(eventType, payload));
}
private onCursorScrollRequest(e: editorCommon.ICursorScrollRequestEvent): void {
......@@ -415,23 +406,31 @@ export class ViewModel extends EventEmitter implements IViewModel {
}
public getLineCount(): number {
return this.lines.getOutputLineCount();
return this.lines.getViewLineCount();
}
/**
* Gives a hint that a lot of requests are about to come in for these line numbers.
*/
public setViewport(startLineNumber: number, endLineNumber: number, centeredLineNumber: number): void {
this._centeredViewLine = centeredLineNumber;
this.lines.warmUpLookupCache(startLineNumber, endLineNumber);
}
public getLineIndentGuide(lineNumber: number): number {
return this.lines.getOutputIndentGuide(lineNumber);
return this.lines.getViewLineIndentGuide(lineNumber);
}
public getLineContent(lineNumber: number): string {
return this.lines.getOutputLineContent(lineNumber);
return this.lines.getViewLineContent(lineNumber);
}
public getLineMinColumn(lineNumber: number): number {
return this.lines.getOutputLineMinColumn(lineNumber);
return this.lines.getViewLineMinColumn(lineNumber);
}
public getLineMaxColumn(lineNumber: number): number {
return this.lines.getOutputLineMaxColumn(lineNumber);
return this.lines.getViewLineMaxColumn(lineNumber);
}
public getLineFirstNonWhitespaceColumn(lineNumber: number): number {
......@@ -485,7 +484,7 @@ export class ViewModel extends EventEmitter implements IViewModel {
let mightContainRTL = this.model.mightContainRTL();
let mightContainNonBasicASCII = this.model.mightContainNonBasicASCII();
let tabSize = this.getTabSize();
let lineData = this.lines.getOutputLineRenderingData(lineNumber);
let lineData = this.lines.getViewLineRenderingData(lineNumber);
let allInlineDecorations = this.decorations.getDecorationsViewportData(visibleRange).inlineDecorations;
let inlineDecorations = allInlineDecorations[lineNumber - visibleRange.startLineNumber];
......@@ -517,7 +516,7 @@ export class ViewModel extends EventEmitter implements IViewModel {
// View -> Model conversion and related methods
public convertViewPositionToModelPosition(viewLineNumber: number, viewColumn: number): Position {
return this.lines.convertOutputPositionToInputPosition(viewLineNumber, viewColumn);
return this.lines.convertViewPositionToModelPosition(viewLineNumber, viewColumn);
}
public convertViewRangeToModelRange(viewRange: Range): Range {
......@@ -547,7 +546,7 @@ export class ViewModel extends EventEmitter implements IViewModel {
}
public convertModelPositionToViewPosition(modelLineNumber: number, modelColumn: number): Position {
return this.lines.convertInputPositionToOutputPosition(modelLineNumber, modelColumn);
return this.lines.convertModelPositionToViewPosition(modelLineNumber, modelColumn);
}
public convertModelRangeToViewRange(modelRange: Range): Range {
......@@ -562,14 +561,8 @@ export class ViewModel extends EventEmitter implements IViewModel {
return new Range(start.lineNumber, start.column, end.lineNumber, end.column);
}
public convertModelSelectionToViewSelection(modelSelection: Selection): Selection {
var selectionStart = this.convertModelPositionToViewPosition(modelSelection.selectionStartLineNumber, modelSelection.selectionStartColumn);
var position = this.convertModelPositionToViewPosition(modelSelection.positionLineNumber, modelSelection.positionColumn);
return new Selection(selectionStart.lineNumber, selectionStart.column, position.lineNumber, position.column);
}
public modelPositionIsVisible(position: Position): boolean {
return this.lines.inputPositionIsVisible(position.lineNumber, position.column);
return this.lines.modelPositionIsVisible(position.lineNumber, position.column);
}
}
\ No newline at end of file
......@@ -18,65 +18,65 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
var model1 = createModel('My First LineMy Second LineAnd another one');
var line1 = createSplitLine([13, 14, 15], '');
assert.equal(line1.getOutputLineCount(), 3);
assert.equal(line1.getOutputLineContent(model1, 1, 0), 'My First Line');
assert.equal(line1.getOutputLineContent(model1, 1, 1), 'My Second Line');
assert.equal(line1.getOutputLineContent(model1, 1, 2), 'And another one');
assert.equal(line1.getOutputLineMaxColumn(model1, 1, 0), 14);
assert.equal(line1.getOutputLineMaxColumn(model1, 1, 1), 15);
assert.equal(line1.getOutputLineMaxColumn(model1, 1, 2), 16);
assert.equal(line1.getViewLineCount(), 3);
assert.equal(line1.getViewLineContent(model1, 1, 0), 'My First Line');
assert.equal(line1.getViewLineContent(model1, 1, 1), 'My Second Line');
assert.equal(line1.getViewLineContent(model1, 1, 2), 'And another one');
assert.equal(line1.getViewLineMaxColumn(model1, 1, 0), 14);
assert.equal(line1.getViewLineMaxColumn(model1, 1, 1), 15);
assert.equal(line1.getViewLineMaxColumn(model1, 1, 2), 16);
for (var col = 1; col <= 14; col++) {
assert.equal(line1.getInputColumnOfOutputPosition(0, col), col, 'getInputColumnOfOutputPosition(0, ' + col + ')');
assert.equal(line1.getModelColumnOfViewPosition(0, col), col, 'getInputColumnOfOutputPosition(0, ' + col + ')');
}
for (var col = 1; col <= 15; col++) {
assert.equal(line1.getInputColumnOfOutputPosition(1, col), 13 + col, 'getInputColumnOfOutputPosition(1, ' + col + ')');
assert.equal(line1.getModelColumnOfViewPosition(1, col), 13 + col, 'getInputColumnOfOutputPosition(1, ' + col + ')');
}
for (var col = 1; col <= 16; col++) {
assert.equal(line1.getInputColumnOfOutputPosition(2, col), 13 + 14 + col, 'getInputColumnOfOutputPosition(2, ' + col + ')');
assert.equal(line1.getModelColumnOfViewPosition(2, col), 13 + 14 + col, 'getInputColumnOfOutputPosition(2, ' + col + ')');
}
for (var col = 1; col <= 13; col++) {
assert.deepEqual(line1.getOutputPositionOfInputPosition(0, col), pos(0, col), 'getOutputPositionOfInputPosition(' + col + ')');
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(0, col), 'getOutputPositionOfInputPosition(' + col + ')');
}
for (var col = 1 + 13; col <= 14 + 13; col++) {
assert.deepEqual(line1.getOutputPositionOfInputPosition(0, col), pos(1, col - 13), 'getOutputPositionOfInputPosition(' + col + ')');
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(1, col - 13), 'getOutputPositionOfInputPosition(' + col + ')');
}
for (var col = 1 + 13 + 14; col <= 15 + 14 + 13; col++) {
assert.deepEqual(line1.getOutputPositionOfInputPosition(0, col), pos(2, col - 13 - 14), 'getOutputPositionOfInputPosition(' + col + ')');
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(2, col - 13 - 14), 'getOutputPositionOfInputPosition(' + col + ')');
}
model1 = createModel('My First LineMy Second LineAnd another one');
line1 = createSplitLine([13, 14, 15], '\t');
assert.equal(line1.getOutputLineCount(), 3);
assert.equal(line1.getOutputLineContent(model1, 1, 0), 'My First Line');
assert.equal(line1.getOutputLineContent(model1, 1, 1), '\tMy Second Line');
assert.equal(line1.getOutputLineContent(model1, 1, 2), '\tAnd another one');
assert.equal(line1.getOutputLineMaxColumn(model1, 1, 0), 14);
assert.equal(line1.getOutputLineMaxColumn(model1, 1, 1), 16);
assert.equal(line1.getOutputLineMaxColumn(model1, 1, 2), 17);
assert.equal(line1.getViewLineCount(), 3);
assert.equal(line1.getViewLineContent(model1, 1, 0), 'My First Line');
assert.equal(line1.getViewLineContent(model1, 1, 1), '\tMy Second Line');
assert.equal(line1.getViewLineContent(model1, 1, 2), '\tAnd another one');
assert.equal(line1.getViewLineMaxColumn(model1, 1, 0), 14);
assert.equal(line1.getViewLineMaxColumn(model1, 1, 1), 16);
assert.equal(line1.getViewLineMaxColumn(model1, 1, 2), 17);
for (var col = 1; col <= 14; col++) {
assert.equal(line1.getInputColumnOfOutputPosition(0, col), col, 'getInputColumnOfOutputPosition(0, ' + col + ')');
assert.equal(line1.getModelColumnOfViewPosition(0, col), col, 'getInputColumnOfOutputPosition(0, ' + col + ')');
}
for (var col = 1; col <= 1; col++) {
assert.equal(line1.getInputColumnOfOutputPosition(1, 1), 13 + col, 'getInputColumnOfOutputPosition(1, ' + col + ')');
assert.equal(line1.getModelColumnOfViewPosition(1, 1), 13 + col, 'getInputColumnOfOutputPosition(1, ' + col + ')');
}
for (var col = 2; col <= 16; col++) {
assert.equal(line1.getInputColumnOfOutputPosition(1, col), 13 + col - 1, 'getInputColumnOfOutputPosition(1, ' + col + ')');
assert.equal(line1.getModelColumnOfViewPosition(1, col), 13 + col - 1, 'getInputColumnOfOutputPosition(1, ' + col + ')');
}
for (var col = 1; col <= 1; col++) {
assert.equal(line1.getInputColumnOfOutputPosition(2, col), 13 + 14 + col, 'getInputColumnOfOutputPosition(2, ' + col + ')');
assert.equal(line1.getModelColumnOfViewPosition(2, col), 13 + 14 + col, 'getInputColumnOfOutputPosition(2, ' + col + ')');
}
for (var col = 2; col <= 17; col++) {
assert.equal(line1.getInputColumnOfOutputPosition(2, col), 13 + 14 + col - 1, 'getInputColumnOfOutputPosition(2, ' + col + ')');
assert.equal(line1.getModelColumnOfViewPosition(2, col), 13 + 14 + col - 1, 'getInputColumnOfOutputPosition(2, ' + col + ')');
}
for (var col = 1; col <= 13; col++) {
assert.deepEqual(line1.getOutputPositionOfInputPosition(0, col), pos(0, col), 'getOutputPositionOfInputPosition(' + col + ')');
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(0, col), 'getOutputPositionOfInputPosition(' + col + ')');
}
for (var col = 1 + 13; col <= 14 + 13; col++) {
assert.deepEqual(line1.getOutputPositionOfInputPosition(0, col), pos(1, 1 + col - 13), 'getOutputPositionOfInputPosition(' + col + ')');
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(1, 1 + col - 13), 'getOutputPositionOfInputPosition(' + col + ')');
}
for (var col = 1 + 13 + 14; col <= 15 + 14 + 13; col++) {
assert.deepEqual(line1.getOutputPositionOfInputPosition(0, col), pos(2, 1 + col - 13 - 14), 'getOutputPositionOfInputPosition(' + col + ')');
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(2, 1 + col - 13 - 14), 'getOutputPositionOfInputPosition(' + col + ')');
}
});
......@@ -126,63 +126,63 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
].join('\n');
withSplitLinesCollection(text, (model, linesCollection) => {
assert.equal(linesCollection.getOutputLineCount(), 6);
assert.equal(linesCollection.getViewLineCount(), 6);
// getOutputIndentGuide
assert.equal(linesCollection.getOutputIndentGuide(-1), 0);
assert.equal(linesCollection.getOutputIndentGuide(0), 0);
assert.equal(linesCollection.getOutputIndentGuide(1), 0);
assert.equal(linesCollection.getOutputIndentGuide(2), 1);
assert.equal(linesCollection.getOutputIndentGuide(3), 0);
assert.equal(linesCollection.getOutputIndentGuide(4), 0);
assert.equal(linesCollection.getOutputIndentGuide(5), 1);
assert.equal(linesCollection.getOutputIndentGuide(6), 0);
assert.equal(linesCollection.getOutputIndentGuide(7), 0);
assert.equal(linesCollection.getViewLineIndentGuide(-1), 0);
assert.equal(linesCollection.getViewLineIndentGuide(0), 0);
assert.equal(linesCollection.getViewLineIndentGuide(1), 0);
assert.equal(linesCollection.getViewLineIndentGuide(2), 1);
assert.equal(linesCollection.getViewLineIndentGuide(3), 0);
assert.equal(linesCollection.getViewLineIndentGuide(4), 0);
assert.equal(linesCollection.getViewLineIndentGuide(5), 1);
assert.equal(linesCollection.getViewLineIndentGuide(6), 0);
assert.equal(linesCollection.getViewLineIndentGuide(7), 0);
// getOutputLineContent
assert.equal(linesCollection.getOutputLineContent(-1), 'int main() {');
assert.equal(linesCollection.getOutputLineContent(0), 'int main() {');
assert.equal(linesCollection.getOutputLineContent(1), 'int main() {');
assert.equal(linesCollection.getOutputLineContent(2), '\tprintf("Hello world!");');
assert.equal(linesCollection.getOutputLineContent(3), '}');
assert.equal(linesCollection.getOutputLineContent(4), 'int main() {');
assert.equal(linesCollection.getOutputLineContent(5), '\tprintf("Hello world!");');
assert.equal(linesCollection.getOutputLineContent(6), '}');
assert.equal(linesCollection.getOutputLineContent(7), '}');
assert.equal(linesCollection.getViewLineContent(-1), 'int main() {');
assert.equal(linesCollection.getViewLineContent(0), 'int main() {');
assert.equal(linesCollection.getViewLineContent(1), 'int main() {');
assert.equal(linesCollection.getViewLineContent(2), '\tprintf("Hello world!");');
assert.equal(linesCollection.getViewLineContent(3), '}');
assert.equal(linesCollection.getViewLineContent(4), 'int main() {');
assert.equal(linesCollection.getViewLineContent(5), '\tprintf("Hello world!");');
assert.equal(linesCollection.getViewLineContent(6), '}');
assert.equal(linesCollection.getViewLineContent(7), '}');
// getOutputLineMinColumn
assert.equal(linesCollection.getOutputLineMinColumn(-1), 1);
assert.equal(linesCollection.getOutputLineMinColumn(0), 1);
assert.equal(linesCollection.getOutputLineMinColumn(1), 1);
assert.equal(linesCollection.getOutputLineMinColumn(2), 1);
assert.equal(linesCollection.getOutputLineMinColumn(3), 1);
assert.equal(linesCollection.getOutputLineMinColumn(4), 1);
assert.equal(linesCollection.getOutputLineMinColumn(5), 1);
assert.equal(linesCollection.getOutputLineMinColumn(6), 1);
assert.equal(linesCollection.getOutputLineMinColumn(7), 1);
assert.equal(linesCollection.getViewLineMinColumn(-1), 1);
assert.equal(linesCollection.getViewLineMinColumn(0), 1);
assert.equal(linesCollection.getViewLineMinColumn(1), 1);
assert.equal(linesCollection.getViewLineMinColumn(2), 1);
assert.equal(linesCollection.getViewLineMinColumn(3), 1);
assert.equal(linesCollection.getViewLineMinColumn(4), 1);
assert.equal(linesCollection.getViewLineMinColumn(5), 1);
assert.equal(linesCollection.getViewLineMinColumn(6), 1);
assert.equal(linesCollection.getViewLineMinColumn(7), 1);
// getOutputLineMaxColumn
assert.equal(linesCollection.getOutputLineMaxColumn(-1), 13);
assert.equal(linesCollection.getOutputLineMaxColumn(0), 13);
assert.equal(linesCollection.getOutputLineMaxColumn(1), 13);
assert.equal(linesCollection.getOutputLineMaxColumn(2), 25);
assert.equal(linesCollection.getOutputLineMaxColumn(3), 2);
assert.equal(linesCollection.getOutputLineMaxColumn(4), 13);
assert.equal(linesCollection.getOutputLineMaxColumn(5), 25);
assert.equal(linesCollection.getOutputLineMaxColumn(6), 2);
assert.equal(linesCollection.getOutputLineMaxColumn(7), 2);
assert.equal(linesCollection.getViewLineMaxColumn(-1), 13);
assert.equal(linesCollection.getViewLineMaxColumn(0), 13);
assert.equal(linesCollection.getViewLineMaxColumn(1), 13);
assert.equal(linesCollection.getViewLineMaxColumn(2), 25);
assert.equal(linesCollection.getViewLineMaxColumn(3), 2);
assert.equal(linesCollection.getViewLineMaxColumn(4), 13);
assert.equal(linesCollection.getViewLineMaxColumn(5), 25);
assert.equal(linesCollection.getViewLineMaxColumn(6), 2);
assert.equal(linesCollection.getViewLineMaxColumn(7), 2);
// convertOutputPositionToInputPosition
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(-1, 1), new Position(1, 1));
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(0, 1), new Position(1, 1));
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(1, 1), new Position(1, 1));
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(2, 1), new Position(2, 1));
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(3, 1), new Position(3, 1));
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(4, 1), new Position(4, 1));
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(5, 1), new Position(5, 1));
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(6, 1), new Position(6, 1));
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(7, 1), new Position(6, 1));
assert.deepEqual(linesCollection.convertOutputPositionToInputPosition(8, 1), new Position(6, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(-1, 1), new Position(1, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(0, 1), new Position(1, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(1, 1), new Position(1, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(2, 1), new Position(2, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(3, 1), new Position(3, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(4, 1), new Position(4, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(5, 1), new Position(5, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(6, 1), new Position(6, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(7, 1), new Position(6, 1));
assert.deepEqual(linesCollection.convertViewPositionToModelPosition(8, 1), new Position(6, 1));
});
});
......@@ -210,7 +210,7 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
endColumn: 1
}], (eventType, payload) => {/*no-op*/ });
let viewLineCount = linesCollection.getOutputLineCount();
let viewLineCount = linesCollection.getViewLineCount();
assert.equal(viewLineCount, 1, 'getOutputLineCount()');
let modelLineCount = model.getLineCount();
......@@ -218,7 +218,7 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
let lineMinColumn = (lineNumber >= 1 && lineNumber <= modelLineCount) ? model.getLineMinColumn(lineNumber) : 1;
let lineMaxColumn = (lineNumber >= 1 && lineNumber <= modelLineCount) ? model.getLineMaxColumn(lineNumber) : 1;
for (let column = lineMinColumn - 1; column <= lineMaxColumn + 1; column++) {
let viewPosition = linesCollection.convertInputPositionToOutputPosition(lineNumber, column);
let viewPosition = linesCollection.convertModelPositionToViewPosition(lineNumber, column);
// validate view position
let viewLineNumber = viewPosition.lineNumber;
......@@ -226,12 +226,12 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
if (viewLineNumber < 1) {
viewLineNumber = 1;
}
var lineCount = linesCollection.getOutputLineCount();
var lineCount = linesCollection.getViewLineCount();
if (viewLineNumber > lineCount) {
viewLineNumber = lineCount;
}
var viewMinColumn = linesCollection.getOutputLineMinColumn(viewLineNumber);
var viewMaxColumn = linesCollection.getOutputLineMaxColumn(viewLineNumber);
var viewMinColumn = linesCollection.getViewLineMinColumn(viewLineNumber);
var viewMaxColumn = linesCollection.getViewLineMaxColumn(viewLineNumber);
if (viewColumn < viewMinColumn) {
viewColumn = viewMinColumn;
}
......@@ -244,10 +244,10 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
}
for (let lineNumber = 0; lineNumber <= viewLineCount + 1; lineNumber++) {
let lineMinColumn = linesCollection.getOutputLineMinColumn(lineNumber);
let lineMaxColumn = linesCollection.getOutputLineMaxColumn(lineNumber);
let lineMinColumn = linesCollection.getViewLineMinColumn(lineNumber);
let lineMaxColumn = linesCollection.getViewLineMaxColumn(lineNumber);
for (let column = lineMinColumn - 1; column <= lineMaxColumn + 1; column++) {
let modelPosition = linesCollection.convertOutputPositionToInputPosition(lineNumber, column);
let modelPosition = linesCollection.convertViewPositionToModelPosition(lineNumber, column);
let validModelPosition = model.validatePosition(modelPosition);
assert.equal(modelPosition.toString(), validModelPosition.toString(), 'view->model for ' + lineNumber + ', ' + column);
}
......
......@@ -47,10 +47,7 @@ suite('ViewModelDecorations', () => {
linesCollection,
EDITOR_ID,
configuration,
model,
() => {
return new Range(1, 1, 1, 1);
}
model
);
callback(viewModel, model);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册