提交 550fd30a 编写于 作者: A Alex Dima

Read minimap render data in bulk

上级 3c28671b
......@@ -404,19 +404,24 @@ export class Minimap extends ViewPart {
let background = this._tokensColorTracker.getColor(ColorId.DefaultBackground);
let data: MinimapLineRenderingData[] = [];
let start = performance.now();
let needed: boolean[] = [];
for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
data[lineNumber - startLineNumber] = this._context.model.getMinimapLineRenderingData(lineNumber);
needed[lineNumber - startLineNumber] = true;
}
const data2 = this._context.model.getMinimapLinesRenderingData(startLineNumber, endLineNumber, needed);
const tabSize = data2.tabSize;
let end = performance.now();
console.log(`FETCHING MINIMAP DATA TOOK ${end - start} ms.`);
// let start = performance.now();
let start2 = performance.now();
let dy = 0;
for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
Minimap._renderLine(imageData, background, renderMinimap, charWidth, this._tokensColorTracker, this._minimapCharRenderer, dy, data[lineNumber - startLineNumber]);
Minimap._renderLine(imageData, background, renderMinimap, charWidth, this._tokensColorTracker, this._minimapCharRenderer, dy, tabSize, data2.data[lineNumber - startLineNumber]);
dy += minimapLineHeight;
}
// let end = performance.now();
// console.log(`INNER LOOP TOOK ${end - start} ms.`);
let end2 = performance.now();
console.log(`PAINTING MINIMAP TOOK ${end2 - start2} ms.`);
ctx.putImageData(imageData, 0, 0);
}
......@@ -429,11 +434,11 @@ export class Minimap extends ViewPart {
colorTracker: MinimapTokensColorTracker,
minimapCharRenderer: MinimapCharRenderer,
dy: number,
tabSize: number,
lineData: MinimapLineRenderingData
): void {
const content = lineData.content;
const tokens = lineData.tokens;
const tabSize = lineData.tabSize;
const maxDx = target.width - charWidth;
let dx = 0;
......
......@@ -10,7 +10,7 @@ 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 { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
import { MinimapLineRenderingData } from 'vs/editor/common/viewModel/viewModel';
import { MinimapLineRenderingData, MinimapLinesRenderingData } from 'vs/editor/common/viewModel/viewModel';
export class OutputPosition {
_outputPositionBrand: void;
......@@ -50,7 +50,8 @@ export interface ISplitLine {
getViewLineMinColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number;
getViewLineMaxColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number;
getViewLineRenderingData(model: IModel, modelLineNumber: number, outputLineIndex: number): OutputLineRenderingData;
getMinimapLineRenderingData(model: IModel, modelLineNumber: number, outputLineIndex: number, tabSize: number): MinimapLineRenderingData;
_getMinimapLineRenderingData(model: IModel, modelLineNumber: number, outputLineIndex: number): MinimapLineRenderingData;
getMinimapLineRenderingData(model: IModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: MinimapLineRenderingData[]): void;
getModelColumnOfViewPosition(outputLineIndex: number, outputColumn: number): number;
getViewPositionOfModelPosition(deltaLineNumber: number, inputColumn: number): Position;
......@@ -100,16 +101,27 @@ class VisibleIdentitySplitLine implements ISplitLine {
);
}
public getMinimapLineRenderingData(model: IModel, modelLineNumber: number, outputLineIndex: number, tabSize: number): MinimapLineRenderingData {
public _getMinimapLineRenderingData(model: IModel, modelLineNumber: number, outputLineIndex: number): MinimapLineRenderingData {
let lineTokens = model.getLineTokens(modelLineNumber, true);
let lineContent = lineTokens.getLineContent();
return new MinimapLineRenderingData(
lineContent,
lineTokens.inflate(),
tabSize
lineTokens.inflate()
);
}
public getMinimapLineRenderingData(model: IModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: MinimapLineRenderingData[]): void {
if (!needed[globalStartIndex]) {
result[globalStartIndex] = null;
return;
}
let lineTokens = model.getLineTokens(modelLineNumber, true);
let lineContent = lineTokens.getLineContent();
result[globalStartIndex] = new MinimapLineRenderingData(
lineContent,
lineTokens.inflate()
);
}
public getModelColumnOfViewPosition(outputLineIndex: number, outputColumn: number): number {
return outputColumn;
......@@ -157,7 +169,11 @@ class InvisibleIdentitySplitLine implements ISplitLine {
throw new Error('Not supported');
}
public getMinimapLineRenderingData(model: IModel, modelLineNumber: number, outputLineIndex: number, tabSize: number): MinimapLineRenderingData {
public _getMinimapLineRenderingData(model: IModel, modelLineNumber: number, outputLineIndex: number): MinimapLineRenderingData {
throw new Error('Not supported');
}
public getMinimapLineRenderingData(model: IModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: MinimapLineRenderingData[]): void {
throw new Error('Not supported');
}
......@@ -276,7 +292,7 @@ export class SplitLine implements ISplitLine {
);
}
public getMinimapLineRenderingData(model: IModel, modelLineNumber: number, outputLineIndex: number, tabSize: number): MinimapLineRenderingData {
public _getMinimapLineRenderingData(model: IModel, modelLineNumber: number, outputLineIndex: number): MinimapLineRenderingData {
if (!this._isVisible) {
throw new Error('Not supported');
}
......@@ -297,11 +313,25 @@ export class SplitLine implements ISplitLine {
return new MinimapLineRenderingData(
lineContent,
lineTokens.sliceAndInflate(startOffset, endOffset, deltaStartIndex),
tabSize
lineTokens.sliceAndInflate(startOffset, endOffset, deltaStartIndex)
);
}
public getMinimapLineRenderingData(model: IModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: MinimapLineRenderingData[]): void {
if (!this._isVisible) {
throw new Error('Not supported');
}
for (let outputLineIndex = fromOuputLineIndex; outputLineIndex < toOutputLineIndex; outputLineIndex++) {
let globalIndex = globalStartIndex + outputLineIndex - fromOuputLineIndex;
if (!needed[globalIndex]) {
result[globalIndex] = null;
continue;
}
result[globalIndex] = this._getMinimapLineRenderingData(model, modelLineNumber, outputLineIndex);
}
}
public getModelColumnOfViewPosition(outputLineIndex: number, outputColumn: number): number {
if (!this._isVisible) {
throw new Error('Not supported');
......@@ -776,16 +806,85 @@ export class SplitLinesCollection {
return this.lines[lineIndex].getViewLineRenderingData(this.model, lineIndex + 1, remainder);
}
public getMinimapLineRenderingData(viewLineNumber: number): MinimapLineRenderingData {
public getMinimapLinesRenderingData(viewStartLineNumber: number, viewEndLineNumber: number, needed: boolean[]): MinimapLinesRenderingData {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
let r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1);
let lineIndex = r.index;
let remainder = r.remainder;
return this.lines[lineIndex].getMinimapLineRenderingData(this.model, lineIndex + 1, remainder, this.tabSize);
}
viewStartLineNumber = this._toValidViewLineNumber(viewStartLineNumber);
viewEndLineNumber = this._toValidViewLineNumber(viewEndLineNumber);
let start = this.prefixSumComputer.getIndexOf(viewStartLineNumber - 1);
let viewLineNumber = viewStartLineNumber;
let startModelLineIndex = start.index;
let startRemainder = start.remainder;
let result: MinimapLineRenderingData[] = [];
for (let modelLineIndex = startModelLineIndex, len = this.model.getLineCount(); modelLineIndex < len; modelLineIndex++) {
let line = this.lines[modelLineIndex];
if (!line.isVisible()) {
continue;
}
let fromViewLineIndex = (modelLineIndex === startModelLineIndex ? startRemainder : 0);
let remainingViewLineCount = line.getViewLineCount() - fromViewLineIndex;
let lastLine = false;
if (viewLineNumber + remainingViewLineCount > viewEndLineNumber) {
lastLine = true;
remainingViewLineCount = viewEndLineNumber - viewLineNumber + 1;
}
let toViewLineIndex = fromViewLineIndex + remainingViewLineCount;
line.getMinimapLineRenderingData(this.model, modelLineIndex + 1, fromViewLineIndex, toViewLineIndex, viewLineNumber - viewStartLineNumber, needed, result);
viewLineNumber += remainingViewLineCount;
if (lastLine) {
break;
}
}
let actual = new MinimapLinesRenderingData(
viewStartLineNumber,
viewEndLineNumber,
this.tabSize,
result
);
// TODO@minimap
// let alternative = this._getMinimapLinesRenderingData(viewStartLineNumber, viewEndLineNumber, needed);
// if (!actual.equals(alternative)) {
// throw new Error('mismatch!');
// }
return actual;
}
// TODO@minimap
// private _getMinimapLinesRenderingData(viewStartLineNumber: number, viewEndLineNumber: number, needed:boolean[]): MinimapLinesRenderingData {
// let result:MinimapLineRenderingData[] = [];
// for (let viewLineNumber = viewStartLineNumber; viewLineNumber <= viewEndLineNumber; viewLineNumber++) {
// let index = viewLineNumber - viewStartLineNumber;
// if (!needed[index]) {
// result[index] = null;
// continue;
// }
// result[index] = this._getMinimapLineRenderingData(viewLineNumber);
// }
// return new MinimapLinesRenderingData(
// viewStartLineNumber,
// viewEndLineNumber,
// this.tabSize,
// result
// );
// }
// private _getMinimapLineRenderingData(viewLineNumber: number): MinimapLineRenderingData {
// viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
// let r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1);
// let lineIndex = r.index;
// let remainder = r.remainder;
// return this.lines[lineIndex]._getMinimapLineRenderingData(this.model, lineIndex + 1, remainder);
// }
public validateViewPosition(viewLineNumber: number, viewColumn: number, expectedModelPosition: Position): Position {
this._ensureValidState();
......
......@@ -72,7 +72,7 @@ export interface IViewModel extends IEventEmitter {
getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];
getViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;
getMinimapLineRenderingData(lineNumber: number): MinimapLineRenderingData;
getMinimapLinesRenderingData(startLineNumber: number, endLineNumber: number, needed: boolean[]): MinimapLinesRenderingData;
getTabSize(): number;
getLineCount(): number;
......@@ -90,6 +90,60 @@ export interface IViewModel extends IEventEmitter {
validateModelPosition(modelPosition: IPosition): Position;
}
export class MinimapLinesRenderingData {
public readonly startLineNumber: number;
public readonly endLineNumber: number;
public readonly tabSize: number;
public readonly data: MinimapLineRenderingData[];
constructor(
startLineNumber: number,
endLineNumber: number,
tabSize: number,
data: MinimapLineRenderingData[]
) {
this.startLineNumber = startLineNumber;
this.endLineNumber = endLineNumber;
this.tabSize = tabSize;
this.data = data;
}
// TODO@minimap
public equals(other: MinimapLinesRenderingData): boolean {
if (this.startLineNumber !== other.startLineNumber) {
return false;
}
if (this.endLineNumber !== other.endLineNumber) {
return false;
}
if (this.tabSize !== other.tabSize) {
return false;
}
let len1 = this.data.length;
let len2 = other.data.length;
if (len1 !== len2) {
return false;
}
for (let i = 0; i < len1; i++) {
let a = this.data[i];
let b = other.data[i];
if (!a && !b) {
continue;
}
if (!a || !b) {
return false;
}
if (a.content !== b.content) {
return false;
}
if (!ViewLineToken.equalsArr(a.tokens, b.tokens)) {
return false;
}
}
return true;
}
}
export class MinimapLineRenderingData {
/**
* The content at this view line.
......@@ -99,19 +153,13 @@ export class MinimapLineRenderingData {
* The tokens at this view line.
*/
public readonly tokens: ViewLineToken[];
/**
* The tab size for this view model.
*/
public readonly tabSize: number;
constructor(
content: string,
tokens: ViewLineToken[],
tabSize: number
tokens: ViewLineToken[]
) {
this.content = content;
this.tokens = tokens;
this.tabSize = tabSize;
}
}
......
......@@ -13,7 +13,7 @@ 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 { MinimapLineRenderingData, ViewLineRenderingData, ViewModelDecoration, IViewModel, ICoordinatesConverter } from 'vs/editor/common/viewModel/viewModel';
import { MinimapLinesRenderingData, ViewLineRenderingData, ViewModelDecoration, IViewModel, ICoordinatesConverter } from 'vs/editor/common/viewModel/viewModel';
import { SplitLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection';
export class CoordinatesConverter implements ICoordinatesConverter {
......@@ -534,8 +534,8 @@ export class ViewModel extends EventEmitter implements IViewModel {
);
}
public getMinimapLineRenderingData(lineNumber: number): MinimapLineRenderingData {
return this.lines.getMinimapLineRenderingData(lineNumber);
public getMinimapLinesRenderingData(startLineNumber: number, endLineNumber: number, needed: boolean[]): MinimapLinesRenderingData {
return this.lines.getMinimapLinesRenderingData(startLineNumber, endLineNumber, needed);
}
public getAllOverviewRulerDecorations(): ViewModelDecoration[] {
......
......@@ -12,6 +12,13 @@ import { ILineMapping, IModel, SplitLine, SplitLinesCollection } from 'vs/editor
import { MockConfiguration } from 'vs/editor/test/common/mocks/mockConfiguration';
import { Model } from 'vs/editor/common/model/model';
import { toUint32Array } from 'vs/editor/common/core/uint';
import * as modes from 'vs/editor/common/modes';
import { NULL_STATE } from 'vs/editor/common/modes/nullMode';
import { TokenizationResult2 } from 'vs/editor/common/core/token';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
import { MinimapLineRenderingData, MinimapLinesRenderingData } from 'vs/editor/common/viewModel/viewModel';
import { Range } from 'vs/editor/common/core/range';
suite('Editor ViewModel - SplitLinesCollection', () => {
test('SplitLine', () => {
......@@ -254,6 +261,461 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
}
});
});
});
suite('SplitLinesCollection', () => {
const _text = [
'class Nice {',
' function hi() {',
' console.log("Hello world");',
' }',
' function hello() {',
' console.log("Hello world, this is a somewhat longer line");',
' }',
'}',
];
const _tokens = [
[
{ startIndex: 0, value: 1 },
{ startIndex: 5, value: 2 },
{ startIndex: 6, value: 3 },
{ startIndex: 10, value: 4 },
],
[
{ startIndex: 0, value: 5 },
{ startIndex: 1, value: 6 },
{ startIndex: 9, value: 7 },
{ startIndex: 10, value: 8 },
{ startIndex: 12, value: 9 },
],
[
{ startIndex: 0, value: 10 },
{ startIndex: 2, value: 11 },
{ startIndex: 9, value: 12 },
{ startIndex: 10, value: 13 },
{ startIndex: 13, value: 14 },
{ startIndex: 14, value: 15 },
{ startIndex: 27, value: 16 },
],
[
{ startIndex: 0, value: 17 },
],
[
{ startIndex: 0, value: 18 },
{ startIndex: 1, value: 19 },
{ startIndex: 9, value: 20 },
{ startIndex: 10, value: 21 },
{ startIndex: 15, value: 22 },
],
[
{ startIndex: 0, value: 23 },
{ startIndex: 2, value: 24 },
{ startIndex: 9, value: 25 },
{ startIndex: 10, value: 26 },
{ startIndex: 13, value: 27 },
{ startIndex: 14, value: 28 },
{ startIndex: 59, value: 29 },
],
[
{ startIndex: 0, value: 30 },
],
[
{ startIndex: 0, value: 31 },
]
];
let model: Model = null;
let languageRegistration: IDisposable = null;
setup(() => {
let _lineIndex = 0;
const tokenizationSupport: modes.ITokenizationSupport = {
getInitialState: () => NULL_STATE,
tokenize: undefined,
tokenize2: (line: string, state: modes.IState): TokenizationResult2 => {
let tokens = _tokens[_lineIndex++];
let result = new Uint32Array(2 * tokens.length);
for (let i = 0; i < tokens.length; i++) {
result[2 * i] = tokens[i].startIndex;
result[2 * i + 1] = (
tokens[i].value << modes.MetadataConsts.FOREGROUND_OFFSET
);
}
return new TokenizationResult2(result, state);
}
};
const LANGUAGE_ID = 'modelModeTest1';
languageRegistration = modes.TokenizationRegistry.register(LANGUAGE_ID, tokenizationSupport);
model = Model.createFromString(_text.join('\n'), undefined, new modes.LanguageIdentifier(LANGUAGE_ID, 0));
// force tokenization
model.getLineTokens(model.getLineCount(), false);
});
teardown(() => {
model.dispose();
model = null;
languageRegistration.dispose();
languageRegistration = null;
});
interface ITestViewLineToken {
endIndex: number;
value: number;
}
function assertViewLineTokens(actual: ViewLineToken[], expected: ITestViewLineToken[]): void {
let _actual = actual.map((token) => {
return {
endIndex: token.endIndex,
value: token.getForeground()
};
});
assert.deepEqual(_actual, expected);
}
interface ITestMinimapLineRenderingData {
content: string;
tokens: ITestViewLineToken[];
}
function assertMinimapLineRenderingData(actual: MinimapLineRenderingData, expected: ITestMinimapLineRenderingData): void {
if (actual === null && expected === null) {
assert.ok(true);
return;
}
assert.equal(actual.content, expected.content);
assertViewLineTokens(actual.tokens, expected.tokens);
}
function assertMinimapLinesRenderingData(actual: MinimapLinesRenderingData, expected: ITestMinimapLineRenderingData[]): void {
assert.equal(actual.data.length, expected.length);
for (let i = 0; i < expected.length; i++) {
assertMinimapLineRenderingData(actual.data[i], expected[i]);
}
}
function assertAllMinimapLinesRenderingData(splitLinesCollection: SplitLinesCollection, all: ITestMinimapLineRenderingData[]): void {
let lineCount = all.length;
for (let start = 1; start <= lineCount; start++) {
for (let end = start; end <= lineCount; end++) {
let count = end - start + 1;
for (let desired = Math.pow(2, count) - 1; desired >= 0; desired--) {
let needed: boolean[] = [];
let expected: ITestMinimapLineRenderingData[] = [];
for (let i = 0; i < count; i++) {
needed[i] = (desired & (1 << i)) ? true : false;
expected[i] = (needed[i] ? all[start - 1 + i] : null);
}
let actual = splitLinesCollection.getMinimapLinesRenderingData(start, end, needed);
assertMinimapLinesRenderingData(actual, expected);
// Remove break to test all possible combinations
break;
}
}
}
}
test('getMinimapLinesRenderingData - no wrapping', () => {
withSplitLinesCollection(model, -1, (splitLinesCollection) => {
assert.equal(splitLinesCollection.getViewLineCount(), 8);
assert.equal(splitLinesCollection.modelPositionIsVisible(1, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(2, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(3, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(4, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(5, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(6, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(7, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(8, 1), true);
let _expected: ITestMinimapLineRenderingData[] = [
{
content: 'class Nice {',
tokens: [
{ endIndex: 5, value: 1 },
{ endIndex: 6, value: 2 },
{ endIndex: 10, value: 3 },
{ endIndex: 12, value: 4 },
]
},
{
content: ' function hi() {',
tokens: [
{ endIndex: 1, value: 5 },
{ endIndex: 9, value: 6 },
{ endIndex: 10, value: 7 },
{ endIndex: 12, value: 8 },
{ endIndex: 16, value: 9 },
]
},
{
content: ' console.log("Hello world");',
tokens: [
{ endIndex: 2, value: 10 },
{ endIndex: 9, value: 11 },
{ endIndex: 10, value: 12 },
{ endIndex: 13, value: 13 },
{ endIndex: 14, value: 14 },
{ endIndex: 27, value: 15 },
{ endIndex: 29, value: 16 },
]
},
{
content: ' }',
tokens: [
{ endIndex: 2, value: 17 },
]
},
{
content: ' function hello() {',
tokens: [
{ endIndex: 1, value: 18 },
{ endIndex: 9, value: 19 },
{ endIndex: 10, value: 20 },
{ endIndex: 15, value: 21 },
{ endIndex: 19, value: 22 },
]
},
{
content: ' console.log("Hello world, this is a somewhat longer line");',
tokens: [
{ endIndex: 2, value: 23 },
{ endIndex: 9, value: 24 },
{ endIndex: 10, value: 25 },
{ endIndex: 13, value: 26 },
{ endIndex: 14, value: 27 },
{ endIndex: 59, value: 28 },
{ endIndex: 61, value: 29 },
]
},
{
content: ' }',
tokens: [
{ endIndex: 2, value: 30 },
]
},
{
content: '}',
tokens: [
{ endIndex: 1, value: 31 },
]
}
];
assertAllMinimapLinesRenderingData(splitLinesCollection, [
_expected[0],
_expected[1],
_expected[2],
_expected[3],
_expected[4],
_expected[5],
_expected[6],
_expected[7],
]);
splitLinesCollection.setHiddenAreas([new Range(2, 1, 4, 1)], () => { });
assert.equal(splitLinesCollection.getViewLineCount(), 5);
assert.equal(splitLinesCollection.modelPositionIsVisible(1, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(2, 1), false);
assert.equal(splitLinesCollection.modelPositionIsVisible(3, 1), false);
assert.equal(splitLinesCollection.modelPositionIsVisible(4, 1), false);
assert.equal(splitLinesCollection.modelPositionIsVisible(5, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(6, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(7, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(8, 1), true);
assertAllMinimapLinesRenderingData(splitLinesCollection, [
_expected[0],
_expected[4],
_expected[5],
_expected[6],
_expected[7],
]);
});
});
test('getMinimapLinesRenderingData - with wrapping', () => {
withSplitLinesCollection(model, 30, (splitLinesCollection) => {
assert.equal(splitLinesCollection.getViewLineCount(), 12);
assert.equal(splitLinesCollection.modelPositionIsVisible(1, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(2, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(3, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(4, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(5, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(6, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(7, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(8, 1), true);
let _expected: ITestMinimapLineRenderingData[] = [
{
content: 'class Nice {',
tokens: [
{ endIndex: 5, value: 1 },
{ endIndex: 6, value: 2 },
{ endIndex: 10, value: 3 },
{ endIndex: 12, value: 4 },
]
},
{
content: ' function hi() {',
tokens: [
{ endIndex: 1, value: 5 },
{ endIndex: 9, value: 6 },
{ endIndex: 10, value: 7 },
{ endIndex: 12, value: 8 },
{ endIndex: 16, value: 9 },
]
},
{
content: ' console.log("Hello ',
tokens: [
{ endIndex: 2, value: 10 },
{ endIndex: 9, value: 11 },
{ endIndex: 10, value: 12 },
{ endIndex: 13, value: 13 },
{ endIndex: 14, value: 14 },
{ endIndex: 21, value: 15 },
]
},
{
content: ' world");',
tokens: [
{ endIndex: 9, value: 15 },
{ endIndex: 11, value: 16 },
]
},
{
content: ' }',
tokens: [
{ endIndex: 2, value: 17 },
]
},
{
content: ' function hello() {',
tokens: [
{ endIndex: 1, value: 18 },
{ endIndex: 9, value: 19 },
{ endIndex: 10, value: 20 },
{ endIndex: 15, value: 21 },
{ endIndex: 19, value: 22 },
]
},
{
content: ' console.log("Hello ',
tokens: [
{ endIndex: 2, value: 23 },
{ endIndex: 9, value: 24 },
{ endIndex: 10, value: 25 },
{ endIndex: 13, value: 26 },
{ endIndex: 14, value: 27 },
{ endIndex: 21, value: 28 },
]
},
{
content: ' world, this is a ',
tokens: [
{ endIndex: 20, value: 28 },
]
},
{
content: ' somewhat longer ',
tokens: [
{ endIndex: 19, value: 28 },
]
},
{
content: ' line");',
tokens: [
{ endIndex: 8, value: 28 },
{ endIndex: 10, value: 29 },
]
},
{
content: ' }',
tokens: [
{ endIndex: 2, value: 30 },
]
},
{
content: '}',
tokens: [
{ endIndex: 1, value: 31 },
]
}
];
assertAllMinimapLinesRenderingData(splitLinesCollection, [
_expected[0],
_expected[1],
_expected[2],
_expected[3],
_expected[4],
_expected[5],
_expected[6],
_expected[7],
_expected[8],
_expected[9],
_expected[10],
_expected[11],
]);
splitLinesCollection.setHiddenAreas([new Range(2, 1, 4, 1)], () => { });
assert.equal(splitLinesCollection.getViewLineCount(), 8);
assert.equal(splitLinesCollection.modelPositionIsVisible(1, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(2, 1), false);
assert.equal(splitLinesCollection.modelPositionIsVisible(3, 1), false);
assert.equal(splitLinesCollection.modelPositionIsVisible(4, 1), false);
assert.equal(splitLinesCollection.modelPositionIsVisible(5, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(6, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(7, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(8, 1), true);
assertAllMinimapLinesRenderingData(splitLinesCollection, [
_expected[0],
_expected[5],
_expected[6],
_expected[7],
_expected[8],
_expected[9],
_expected[10],
_expected[11],
]);
});
});
function withSplitLinesCollection(model: Model, wrappingColumn: number, callback: (splitLinesCollection: SplitLinesCollection) => void): void {
let configuration = new MockConfiguration({
wrappingColumn: wrappingColumn,
wrappingIndent: 'indent'
});
let factory = new CharacterHardWrappingLineMapperFactory(
configuration.editor.wrappingInfo.wordWrapBreakBeforeCharacters,
configuration.editor.wrappingInfo.wordWrapBreakAfterCharacters,
configuration.editor.wrappingInfo.wordWrapBreakObtrusiveCharacters
);
let linesCollection = new SplitLinesCollection(
model,
factory,
model.getOptions().tabSize,
configuration.editor.wrappingInfo.wrappingColumn,
configuration.editor.fontInfo.typicalFullwidthCharacterWidth / configuration.editor.fontInfo.typicalHalfwidthCharacterWidth,
configuration.editor.wrappingInfo.wrappingIndent
);
callback(linesCollection);
configuration.dispose();
}
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册