提交 ba5b15d6 编写于 作者: A Alex Dima

Clean up CursorMoveHelper

上级 1991f8b6
......@@ -6,95 +6,105 @@
import { IPosition } from 'vs/editor/common/editorCommon';
import { Selection } from 'vs/editor/common/core/selection';
import { CharCode } from 'vs/base/common/charCode';
import * as strings from 'vs/base/common/strings';
export interface IMoveResult {
lineNumber: number;
column: number;
leftoverVisibleColumns: number;
}
export class CursorMoveConfiguration {
_cursorMoveConfigurationBrand: void;
export interface IViewColumnSelectResult {
viewSelections: Selection[];
reversed: boolean;
}
export interface IColumnSelectResult extends IViewColumnSelectResult {
selections: Selection[];
toLineNumber: number;
toVisualColumn: number;
public readonly tabSize: number;
constructor(
tabSize: number
) {
this.tabSize = tabSize;
}
}
export interface ICursorMoveHelperModel {
getLineCount(): number;
getLineFirstNonWhitespaceColumn(lineNumber: number): number;
getLineContent(lineNumber: number): string;
getLineMinColumn(lineNumber: number): number;
getLineMaxColumn(lineNumber: number): number;
getLineFirstNonWhitespaceColumn(lineNumber: number): number;
getLineLastNonWhitespaceColumn(lineNumber: number): number;
getLineContent(lineNumber: number): string;
}
/**
* Internal indentation options (computed) for the editor.
*/
export interface IInternalIndentationOptions {
/**
* Tab size in spaces. This is used for rendering and for editing.
*/
tabSize: number;
}
export class CursorMoveResult {
_cursorMoveResultBrand: void;
export interface IConfiguration {
getIndentationOptions(): IInternalIndentationOptions;
}
public readonly lineNumber: number;
public readonly column: number;
public readonly leftoverVisibleColumns: number;
function isHighSurrogate(model: ICursorMoveHelperModel, lineNumber: number, column: number) {
return strings.isHighSurrogate(model.getLineContent(lineNumber).charCodeAt(column - 1));
constructor(lineNumber: number, column: number, leftoverVisibleColumns: number) {
this.lineNumber = lineNumber;
this.column = column;
this.leftoverVisibleColumns = leftoverVisibleColumns;
}
}
function isLowSurrogate(model: ICursorMoveHelperModel, lineNumber: number, column: number) {
return strings.isLowSurrogate(model.getLineContent(lineNumber).charCodeAt(column - 1));
}
/**
* Common operations that work and make sense both on the model and on the view model.
*/
export class CursorMove {
export class CursorMoveHelper {
private static _isLowSurrogate(model: ICursorMoveHelperModel, lineNumber: number, charOffset: number): boolean {
let lineContent = model.getLineContent(lineNumber);
if (charOffset < 0 || charOffset >= lineContent.length) {
return false;
}
return strings.isLowSurrogate(lineContent.charCodeAt(charOffset));
}
private readonly _tabSize: number;
private static _isHighSurrogate(model: ICursorMoveHelperModel, lineNumber: number, charOffset: number): boolean {
let lineContent = model.getLineContent(lineNumber);
if (charOffset < 0 || charOffset >= lineContent.length) {
return false;
}
return strings.isHighSurrogate(lineContent.charCodeAt(charOffset));
}
constructor(tabSize: number) {
this._tabSize = tabSize;
private static _isInsideSurrogatePair(model: ICursorMoveHelperModel, lineNumber: number, column: number): boolean {
return this._isHighSurrogate(model, lineNumber, column - 2);
}
public getLeftOfPosition(model: ICursorMoveHelperModel, lineNumber: number, column: number): IPosition {
public static left(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, column: number): CursorMoveResult {
if (column > model.getLineMinColumn(lineNumber)) {
column = column - (isLowSurrogate(model, lineNumber, column - 1) ? 2 : 1);
if (this._isLowSurrogate(model, lineNumber, column - 2)) {
// character before column is a low surrogate
column = column - 2;
} else {
column = column - 1;
}
} else if (lineNumber > 1) {
lineNumber = lineNumber - 1;
column = model.getLineMaxColumn(lineNumber);
}
return {
lineNumber: lineNumber,
column: column
};
return new CursorMoveResult(lineNumber, column, 0);
}
public getRightOfPosition(model: ICursorMoveHelperModel, lineNumber: number, column: number): IPosition {
public static right(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, column: number): CursorMoveResult {
if (column < model.getLineMaxColumn(lineNumber)) {
column = column + (isHighSurrogate(model, lineNumber, column) ? 2 : 1);
if (this._isHighSurrogate(model, lineNumber, column - 1)) {
// character after column is a high surrogate
column = column + 2;
} else {
column = column + 1;
}
} else if (lineNumber < model.getLineCount()) {
lineNumber = lineNumber + 1;
column = model.getLineMinColumn(lineNumber);
}
return {
lineNumber: lineNumber,
column: column
};
return new CursorMoveResult(lineNumber, column, 0);
}
public getPositionUp(model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnFirstLine: boolean): IMoveResult {
var currentVisibleColumn = this.visibleColumnFromColumn(model, lineNumber, column) + leftoverVisibleColumns;
public static up(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnFirstLine: boolean): CursorMoveResult {
const currentVisibleColumn = this.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize) + leftoverVisibleColumns;
lineNumber = lineNumber - count;
if (lineNumber < 1) {
......@@ -103,22 +113,24 @@ export class CursorMoveHelper {
column = model.getLineMinColumn(lineNumber);
} else {
column = Math.min(model.getLineMaxColumn(lineNumber), column);
if (this._isInsideSurrogatePair(model, lineNumber, column)) {
column = column - 1;
}
}
} else {
column = this.columnFromVisibleColumn(model, lineNumber, currentVisibleColumn);
column = this.columnFromVisibleColumn(config, model, lineNumber, currentVisibleColumn);
if (this._isInsideSurrogatePair(model, lineNumber, column)) {
column = column - 1;
}
}
leftoverVisibleColumns = currentVisibleColumn - this.visibleColumnFromColumn(model, lineNumber, column);
leftoverVisibleColumns = currentVisibleColumn - this.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize);
return {
lineNumber: lineNumber,
column: column,
leftoverVisibleColumns: leftoverVisibleColumns
};
return new CursorMoveResult(lineNumber, column, leftoverVisibleColumns);
}
public getPositionDown(model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnLastLine: boolean): IMoveResult {
var currentVisibleColumn = this.visibleColumnFromColumn(model, lineNumber, column) + leftoverVisibleColumns;
public static down(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnLastLine: boolean): CursorMoveResult {
const currentVisibleColumn = this.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize) + leftoverVisibleColumns;
lineNumber = lineNumber + count;
var lineCount = model.getLineCount();
......@@ -128,17 +140,135 @@ export class CursorMoveHelper {
column = model.getLineMaxColumn(lineNumber);
} else {
column = Math.min(model.getLineMaxColumn(lineNumber), column);
if (this._isInsideSurrogatePair(model, lineNumber, column)) {
column = column - 1;
}
}
} else {
column = this.columnFromVisibleColumn(model, lineNumber, currentVisibleColumn);
column = this.columnFromVisibleColumn(config, model, lineNumber, currentVisibleColumn);
if (this._isInsideSurrogatePair(model, lineNumber, column)) {
column = column - 1;
}
}
leftoverVisibleColumns = currentVisibleColumn - this.visibleColumnFromColumn(model, lineNumber, column);
return {
lineNumber: lineNumber,
column: column,
leftoverVisibleColumns: leftoverVisibleColumns
};
leftoverVisibleColumns = currentVisibleColumn - this.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize);
return new CursorMoveResult(lineNumber, column, leftoverVisibleColumns);
}
public static visibleColumnFromColumn(lineContent: string, column: number, tabSize: number): number {
let endOffset = lineContent.length;
if (endOffset > column - 1) {
endOffset = column - 1;
}
let result = 0;
for (let i = 0; i < endOffset; i++) {
let charCode = lineContent.charCodeAt(i);
if (charCode === CharCode.Tab) {
result = this.nextTabStop(result, tabSize);
} else {
result = result + 1;
}
}
return result;
}
private static _columnFromVisibleColumn(lineContent: string, visibleColumn: number, tabSize: number): number {
if (visibleColumn <= 0) {
return 1;
}
const lineLength = lineContent.length;
let beforeVisibleColumn = 0;
for (let i = 0; i < lineLength; i++) {
let charCode = lineContent.charCodeAt(i);
let afterVisibleColumn: number;
if (charCode === CharCode.Tab) {
afterVisibleColumn = this.nextTabStop(beforeVisibleColumn, tabSize);
} else {
afterVisibleColumn = beforeVisibleColumn + 1;
}
if (afterVisibleColumn >= visibleColumn) {
let prevDelta = visibleColumn - beforeVisibleColumn;
let afterDelta = afterVisibleColumn - visibleColumn;
if (afterDelta < prevDelta) {
return i + 2;
} else {
return i + 1;
}
}
beforeVisibleColumn = afterVisibleColumn;
}
// walked the entire string
return lineLength + 1;
}
public static columnFromVisibleColumn(config: CursorMoveConfiguration, model: ICursorMoveHelperModel, lineNumber: number, visibleColumn: number): number {
let result = this._columnFromVisibleColumn(model.getLineContent(lineNumber), visibleColumn, config.tabSize);
let minColumn = model.getLineMinColumn(lineNumber);
if (result < minColumn) {
return minColumn;
}
let maxColumn = model.getLineMaxColumn(lineNumber);
if (result > maxColumn) {
return maxColumn;
}
return result;
}
/**
* ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)
*/
public static nextTabStop(visibleColumn: number, tabSize: number): number {
return visibleColumn + tabSize - visibleColumn % tabSize;
}
}
export interface IViewColumnSelectResult {
viewSelections: Selection[];
reversed: boolean;
}
export interface IColumnSelectResult extends IViewColumnSelectResult {
selections: Selection[];
toLineNumber: number;
toVisualColumn: number;
}
export class CursorMoveHelper {
private readonly _tabSize: number;
private readonly _config: CursorMoveConfiguration;
constructor(tabSize: number) {
this._tabSize = tabSize;
this._config = new CursorMoveConfiguration(this._tabSize);
}
public getLeftOfPosition(model: ICursorMoveHelperModel, lineNumber: number, column: number): IPosition {
return CursorMove.left(this._config, model, lineNumber, column);
}
public getRightOfPosition(model: ICursorMoveHelperModel, lineNumber: number, column: number): IPosition {
return CursorMove.right(this._config, model, lineNumber, column);
}
public getPositionUp(model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnFirstLine: boolean): CursorMoveResult {
return CursorMove.up(this._config, model, lineNumber, column, leftoverVisibleColumns, count, allowMoveOnFirstLine);
}
public getPositionDown(model: ICursorMoveHelperModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnLastLine: boolean): CursorMoveResult {
return CursorMove.down(this._config, model, lineNumber, column, leftoverVisibleColumns, count, allowMoveOnLastLine);
}
public columnSelect(model: ICursorMoveHelperModel, fromLineNumber: number, fromVisibleColumn: number, toLineNumber: number, toVisibleColumn: number): IViewColumnSelectResult {
......@@ -223,47 +353,18 @@ export class CursorMoveHelper {
}
public static visibleColumnFromColumn2(line: string, column: number, tabSize: number): number {
var result = 0;
for (var i = 0; i < column - 1; i++) {
result = (line.charAt(i) === '\t') ? CursorMoveHelper.nextTabColumn(result, tabSize) : result + 1;
}
return result;
return CursorMove.visibleColumnFromColumn(line, column, tabSize);
}
public columnFromVisibleColumn(model: ICursorMoveHelperModel, lineNumber: number, visibleColumn: number): number {
var line = model.getLineContent(lineNumber);
var lastVisibleColumn = -1;
var thisVisibleColumn = 0;
for (var i = 0; i < line.length && thisVisibleColumn <= visibleColumn; i++) {
lastVisibleColumn = thisVisibleColumn;
thisVisibleColumn = (line.charAt(i) === '\t') ? CursorMoveHelper.nextTabColumn(thisVisibleColumn, this._tabSize) : thisVisibleColumn + 1;
}
// Choose the closest
thisVisibleColumn = Math.abs(visibleColumn - thisVisibleColumn);
lastVisibleColumn = Math.abs(visibleColumn - lastVisibleColumn);
var result: number;
if (thisVisibleColumn < lastVisibleColumn) {
result = i + 1;
} else {
result = i;
}
var minColumn = model.getLineMinColumn(lineNumber);
if (result < minColumn) {
result = minColumn;
}
return result;
return CursorMove.columnFromVisibleColumn(this._config, model, lineNumber, visibleColumn);
}
/**
* ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)
*/
public static nextTabColumn(column: number, tabSize: number): number {
return column + tabSize - column % tabSize;
return CursorMove.nextTabStop(column, tabSize);
}
/**
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import * as strings from 'vs/base/common/strings';
import { CursorMoveHelper, ICursorMoveHelperModel } from 'vs/editor/common/controller/cursorMoveHelper';
suite('CursorMove', () => {
test('nextTabStop', () => {
assert.equal(CursorMoveHelper.nextTabColumn(0, 4), 4);
assert.equal(CursorMoveHelper.nextTabColumn(1, 4), 4);
assert.equal(CursorMoveHelper.nextTabColumn(2, 4), 4);
assert.equal(CursorMoveHelper.nextTabColumn(3, 4), 4);
assert.equal(CursorMoveHelper.nextTabColumn(4, 4), 8);
assert.equal(CursorMoveHelper.nextTabColumn(5, 4), 8);
assert.equal(CursorMoveHelper.nextTabColumn(6, 4), 8);
assert.equal(CursorMoveHelper.nextTabColumn(7, 4), 8);
assert.equal(CursorMoveHelper.nextTabColumn(8, 4), 12);
assert.equal(CursorMoveHelper.nextTabColumn(0, 2), 2);
assert.equal(CursorMoveHelper.nextTabColumn(1, 2), 2);
assert.equal(CursorMoveHelper.nextTabColumn(2, 2), 4);
assert.equal(CursorMoveHelper.nextTabColumn(3, 2), 4);
assert.equal(CursorMoveHelper.nextTabColumn(4, 2), 6);
assert.equal(CursorMoveHelper.nextTabColumn(5, 2), 6);
assert.equal(CursorMoveHelper.nextTabColumn(6, 2), 8);
assert.equal(CursorMoveHelper.nextTabColumn(7, 2), 8);
assert.equal(CursorMoveHelper.nextTabColumn(8, 2), 10);
assert.equal(CursorMoveHelper.nextTabColumn(0, 1), 1);
assert.equal(CursorMoveHelper.nextTabColumn(1, 1), 2);
assert.equal(CursorMoveHelper.nextTabColumn(2, 1), 3);
assert.equal(CursorMoveHelper.nextTabColumn(3, 1), 4);
assert.equal(CursorMoveHelper.nextTabColumn(4, 1), 5);
assert.equal(CursorMoveHelper.nextTabColumn(5, 1), 6);
assert.equal(CursorMoveHelper.nextTabColumn(6, 1), 7);
assert.equal(CursorMoveHelper.nextTabColumn(7, 1), 8);
assert.equal(CursorMoveHelper.nextTabColumn(8, 1), 9);
});
class OneLineModel implements ICursorMoveHelperModel {
private _line: string;
constructor(line: string) {
this._line = line;
}
getLineCount(): number {
return 1;
}
getLineContent(lineNumber: number): string {
return this._line;
}
getLineMinColumn(lineNumber: number): number {
return 1;
}
getLineMaxColumn(lineNumber: number): number {
return this._line.length + 1;
}
getLineFirstNonWhitespaceColumn(lineNumber: number): number {
let result = strings.firstNonWhitespaceIndex(this._line);
if (result === -1) {
return 0;
}
return result + 1;
}
getLineLastNonWhitespaceColumn(lineNumber: number): number {
let result = strings.lastNonWhitespaceIndex(this._line);
if (result === -1) {
return 0;
}
return result + 2;
}
}
test('visibleColumnFromColumn', () => {
function testVisibleColumnFromColumn(text:string, tabSize:number, column:number, expected:number): void {
let helper = new CursorMoveHelper(tabSize);
let model = new OneLineModel(text);
assert.equal(helper.visibleColumnFromColumn(model, 1, column), expected);
}
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 1, 0);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 2, 4);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 3, 8);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 4, 9);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 5, 10);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 6, 11);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 7, 12);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 8, 13);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 9, 14);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 10, 15);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 11, 16);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 12, 17);
testVisibleColumnFromColumn('\t\tvar x = 3;', 4, 13, 18);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 1, 0);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 2, 4);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 3, 5);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 4, 8);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 5, 9);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 6, 10);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 7, 11);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 8, 12);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 9, 13);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 10, 14);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 11, 15);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 12, 16);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 13, 17);
testVisibleColumnFromColumn('\t \tvar x = 3;', 4, 14, 18);
testVisibleColumnFromColumn('\t \tx\t', 4, -1, 0);
testVisibleColumnFromColumn('\t \tx\t', 4, 0, 0);
testVisibleColumnFromColumn('\t \tx\t', 4, 1, 0);
testVisibleColumnFromColumn('\t \tx\t', 4, 2, 4);
testVisibleColumnFromColumn('\t \tx\t', 4, 3, 5);
testVisibleColumnFromColumn('\t \tx\t', 4, 4, 6);
testVisibleColumnFromColumn('\t \tx\t', 4, 5, 8);
testVisibleColumnFromColumn('\t \tx\t', 4, 6, 9);
testVisibleColumnFromColumn('\t \tx\t', 4, 7, 12);
testVisibleColumnFromColumn('\t \tx\t', 4, 8, 12);
testVisibleColumnFromColumn('\t \tx\t', 4, 9, 12);
testVisibleColumnFromColumn('baz', 4, 1, 0);
testVisibleColumnFromColumn('baz', 4, 2, 1);
testVisibleColumnFromColumn('baz', 4, 3, 2);
testVisibleColumnFromColumn('baz', 4, 4, 3);
testVisibleColumnFromColumn('📚az', 4, 1, 0);
testVisibleColumnFromColumn('📚az', 4, 2, 1);
testVisibleColumnFromColumn('📚az', 4, 3, 2);
testVisibleColumnFromColumn('📚az', 4, 4, 3);
testVisibleColumnFromColumn('📚az', 4, 5, 4);
});
test('columnFromVisibleColumn', () => {
function testColumnFromVisibleColumn(text:string, tabSize:number, visibleColumn:number, expected:number): void {
let helper = new CursorMoveHelper(tabSize);
let model = new OneLineModel(text);
assert.equal(helper.columnFromVisibleColumn(model, 1, visibleColumn), expected);
}
// testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 0, 1);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 1, 1);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 2, 1);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 3, 2);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 4, 2);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 5, 2);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 6, 2);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 7, 3);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 8, 3);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 9, 4);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 10, 5);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 11, 6);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 12, 7);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 13, 8);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 14, 9);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 15, 10);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 16, 11);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 17, 12);
testColumnFromVisibleColumn('\t\tvar x = 3;', 4, 18, 13);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 0, 1);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 1, 1);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 2, 1);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 3, 2);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 4, 2);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 5, 3);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 6, 3);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 7, 4);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 8, 4);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 9, 5);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 10, 6);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 11, 7);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 12, 8);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 13, 9);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 14, 10);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 15, 11);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 16, 12);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 17, 13);
testColumnFromVisibleColumn('\t \tvar x = 3;', 4, 18, 14);
testColumnFromVisibleColumn('\t \tx\t', 4, -2, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, -1, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, 0, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, 1, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, 2, 1);
testColumnFromVisibleColumn('\t \tx\t', 4, 3, 2);
testColumnFromVisibleColumn('\t \tx\t', 4, 4, 2);
testColumnFromVisibleColumn('\t \tx\t', 4, 5, 3);
testColumnFromVisibleColumn('\t \tx\t', 4, 6, 4);
testColumnFromVisibleColumn('\t \tx\t', 4, 7, 4);
testColumnFromVisibleColumn('\t \tx\t', 4, 8, 5);
testColumnFromVisibleColumn('\t \tx\t', 4, 9, 6);
testColumnFromVisibleColumn('\t \tx\t', 4, 10, 6);
testColumnFromVisibleColumn('\t \tx\t', 4, 11, 7);
testColumnFromVisibleColumn('\t \tx\t', 4, 12, 7);
testColumnFromVisibleColumn('\t \tx\t', 4, 13, 7);
testColumnFromVisibleColumn('\t \tx\t', 4, 14, 7);
testColumnFromVisibleColumn('baz', 4, 0, 1);
testColumnFromVisibleColumn('baz', 4, 1, 2);
testColumnFromVisibleColumn('baz', 4, 2, 3);
testColumnFromVisibleColumn('baz', 4, 3, 4);
testColumnFromVisibleColumn('📚az', 4, 0, 1);
testColumnFromVisibleColumn('📚az', 4, 1, 2);
testColumnFromVisibleColumn('📚az', 4, 2, 3);
testColumnFromVisibleColumn('📚az', 4, 3, 4);
testColumnFromVisibleColumn('📚az', 4, 4, 5);
});
});
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册