mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Initial VS Code 1.19 source merge (#571)
* Initial 1.19 xcopy * Fix yarn build * Fix numerous build breaks * Next batch of build break fixes * More build break fixes * Runtime breaks * Additional post merge fixes * Fix windows setup file * Fix test failures. * Update license header blocks to refer to source eula
This commit is contained in:
@@ -1,94 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
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 { Model } from 'vs/editor/common/model/model';
|
||||
import { LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
import { withMockCodeEditor } from 'vs/editor/test/common/mocks/mockCodeEditor';
|
||||
|
||||
export function testCommand(
|
||||
lines: string[],
|
||||
languageIdentifier: LanguageIdentifier,
|
||||
selection: Selection,
|
||||
commandFactory: (selection: Selection) => editorCommon.ICommand,
|
||||
expectedLines: string[],
|
||||
expectedSelection: Selection
|
||||
): void {
|
||||
let model = Model.createFromString(lines.join('\n'), undefined, languageIdentifier);
|
||||
withMockCodeEditor(null, { model: model }, (editor, cursor) => {
|
||||
|
||||
cursor.setSelections('tests', [selection]);
|
||||
|
||||
cursor.trigger('tests', editorCommon.Handler.ExecuteCommand, commandFactory(cursor.getSelection()));
|
||||
|
||||
assert.deepEqual(model.getLinesContent(), expectedLines);
|
||||
|
||||
let actualSelection = cursor.getSelection();
|
||||
assert.deepEqual(actualSelection.toString(), expectedSelection.toString());
|
||||
|
||||
});
|
||||
model.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract edit operations if command `command` were to execute on model `model`
|
||||
*/
|
||||
export function getEditOperation(model: editorCommon.IModel, command: editorCommon.ICommand): editorCommon.IIdentifiedSingleEditOperation[] {
|
||||
var operations: editorCommon.IIdentifiedSingleEditOperation[] = [];
|
||||
var editOperationBuilder: editorCommon.IEditOperationBuilder = {
|
||||
addEditOperation: (range: Range, text: string) => {
|
||||
operations.push({
|
||||
identifier: null,
|
||||
range: range,
|
||||
text: text,
|
||||
forceMoveMarkers: false
|
||||
});
|
||||
},
|
||||
|
||||
addTrackedEditOperation: (range: Range, text: string) => {
|
||||
operations.push({
|
||||
identifier: null,
|
||||
range: range,
|
||||
text: text,
|
||||
forceMoveMarkers: false
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
trackSelection: (selection: Selection) => {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
command.getEditOperations(model, editOperationBuilder);
|
||||
return operations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create single edit operation
|
||||
*/
|
||||
export function createSingleEditOp(text: string, positionLineNumber: number, positionColumn: number, selectionLineNumber: number = positionLineNumber, selectionColumn: number = positionColumn): editorCommon.IIdentifiedSingleEditOperation {
|
||||
return {
|
||||
identifier: null,
|
||||
range: new Range(selectionLineNumber, selectionColumn, positionLineNumber, positionColumn),
|
||||
text: text,
|
||||
forceMoveMarkers: false
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create single edit operation
|
||||
*/
|
||||
export function createInsertDeleteSingleEditOp(text: string, positionLineNumber: number, positionColumn: number, selectionLineNumber: number = positionLineNumber, selectionColumn: number = positionColumn): editorCommon.IIdentifiedSingleEditOperation {
|
||||
return {
|
||||
identifier: null,
|
||||
range: new Range(selectionLineNumber, selectionColumn, positionLineNumber, positionColumn),
|
||||
text: text,
|
||||
forceMoveMarkers: true
|
||||
};
|
||||
}
|
||||
@@ -1,987 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { ShiftCommand } from 'vs/editor/common/commands/shiftCommand';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { IIdentifiedSingleEditOperation } from 'vs/editor/common/editorCommon';
|
||||
import { IndentAction } from 'vs/editor/common/modes/languageConfiguration';
|
||||
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
|
||||
import { createSingleEditOp, getEditOperation, testCommand } from 'vs/editor/test/common/commands/commandTestUtils';
|
||||
import { withEditorModel } from 'vs/editor/test/common/editorTestUtils';
|
||||
import { MockMode } from 'vs/editor/test/common/mocks/mockMode';
|
||||
import { LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
|
||||
class DocBlockCommentMode extends MockMode {
|
||||
|
||||
private static _id = new LanguageIdentifier('commentMode', 3);
|
||||
|
||||
constructor() {
|
||||
super(DocBlockCommentMode._id);
|
||||
this._register(LanguageConfigurationRegistry.register(this.getLanguageIdentifier(), {
|
||||
brackets: [
|
||||
['(', ')'],
|
||||
['{', '}'],
|
||||
['[', ']']
|
||||
],
|
||||
|
||||
onEnterRules: [
|
||||
{
|
||||
// e.g. /** | */
|
||||
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
|
||||
afterText: /^\s*\*\/$/,
|
||||
action: { indentAction: IndentAction.IndentOutdent, appendText: ' * ' }
|
||||
},
|
||||
{
|
||||
// e.g. /** ...|
|
||||
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
|
||||
action: { indentAction: IndentAction.None, appendText: ' * ' }
|
||||
},
|
||||
{
|
||||
// e.g. * ...|
|
||||
beforeText: /^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
|
||||
action: { indentAction: IndentAction.None, appendText: '* ' }
|
||||
},
|
||||
{
|
||||
// e.g. */|
|
||||
beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/,
|
||||
action: { indentAction: IndentAction.None, removeText: 1 }
|
||||
},
|
||||
{
|
||||
// e.g. *-----*/|
|
||||
beforeText: /^(\t|(\ \ ))*\ \*[^/]*\*\/\s*$/,
|
||||
action: { indentAction: IndentAction.None, removeText: 1 }
|
||||
}
|
||||
]
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
function testShiftCommand(lines: string[], languageIdentifier: LanguageIdentifier, useTabStops: boolean, selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
|
||||
testCommand(lines, languageIdentifier, selection, (sel) => new ShiftCommand(sel, {
|
||||
isUnshift: false,
|
||||
tabSize: 4,
|
||||
oneIndent: '\t',
|
||||
useTabStops: useTabStops,
|
||||
}), expectedLines, expectedSelection);
|
||||
}
|
||||
|
||||
function testUnshiftCommand(lines: string[], languageIdentifier: LanguageIdentifier, useTabStops: boolean, selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
|
||||
testCommand(lines, languageIdentifier, selection, (sel) => new ShiftCommand(sel, {
|
||||
isUnshift: true,
|
||||
tabSize: 4,
|
||||
oneIndent: '\t',
|
||||
useTabStops: useTabStops,
|
||||
}), expectedLines, expectedSelection);
|
||||
}
|
||||
|
||||
function withDockBlockCommentMode(callback: (mode: DocBlockCommentMode) => void): void {
|
||||
let mode = new DocBlockCommentMode();
|
||||
callback(mode);
|
||||
mode.dispose();
|
||||
}
|
||||
|
||||
suite('Editor Commands - ShiftCommand', () => {
|
||||
|
||||
// --------- shift
|
||||
|
||||
test('Bug 9503: Shifting without any selection', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 1, 1, 1),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 1, 1, 2)
|
||||
);
|
||||
});
|
||||
|
||||
test('shift on single line selection 1', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 3, 1, 1),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 4, 1, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('shift on single line selection 2', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 1, 1, 3),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 1, 1, 4)
|
||||
);
|
||||
});
|
||||
|
||||
test('simple shift', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 1, 2, 1),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 1, 2, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('shifting on two separate lines', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 1, 2, 1),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 1, 2, 1)
|
||||
);
|
||||
|
||||
testShiftCommand(
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(2, 1, 3, 1),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(2, 1, 3, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('shifting on two lines', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 2, 2, 2),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 3, 2, 2)
|
||||
);
|
||||
});
|
||||
|
||||
test('shifting on two lines again', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(2, 2, 1, 2),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(2, 2, 1, 3)
|
||||
);
|
||||
});
|
||||
|
||||
test('shifting at end of file', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(4, 1, 5, 2),
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'\t123'
|
||||
],
|
||||
new Selection(4, 1, 5, 3)
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #1120 TAB should not indent empty lines in a multi-line selection', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 1, 5, 2),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\t\t\tMy Second Line',
|
||||
'\t\tThird Line',
|
||||
'',
|
||||
'\t123'
|
||||
],
|
||||
new Selection(1, 1, 5, 3)
|
||||
);
|
||||
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(4, 1, 5, 1),
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'\t',
|
||||
'123'
|
||||
],
|
||||
new Selection(4, 1, 5, 1)
|
||||
);
|
||||
});
|
||||
|
||||
// --------- unshift
|
||||
|
||||
test('unshift on single line selection 1', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(2, 3, 2, 1),
|
||||
[
|
||||
'My First Line',
|
||||
'\t\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(2, 3, 2, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('unshift on single line selection 2', () => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(2, 1, 2, 3),
|
||||
[
|
||||
'My First Line',
|
||||
'\t\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(2, 1, 2, 3)
|
||||
);
|
||||
});
|
||||
|
||||
test('simple unshift', () => {
|
||||
testUnshiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 1, 2, 1),
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 1, 2, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('unshifting on two lines 1', () => {
|
||||
testUnshiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 2, 2, 2),
|
||||
[
|
||||
'My First Line',
|
||||
'\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 2, 2, 2)
|
||||
);
|
||||
});
|
||||
|
||||
test('unshifting on two lines 2', () => {
|
||||
testUnshiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(2, 3, 2, 1),
|
||||
[
|
||||
'My First Line',
|
||||
'\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(2, 2, 2, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('unshifting at the end of the file', () => {
|
||||
testUnshiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(4, 1, 5, 2),
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(4, 1, 5, 2)
|
||||
);
|
||||
});
|
||||
|
||||
test('unshift many times + shift', () => {
|
||||
testUnshiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 1, 5, 4),
|
||||
[
|
||||
'My First Line',
|
||||
'\tMy Second Line',
|
||||
'Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 1, 5, 4)
|
||||
);
|
||||
|
||||
testUnshiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\tMy Second Line',
|
||||
'Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 1, 5, 4),
|
||||
[
|
||||
'My First Line',
|
||||
'My Second Line',
|
||||
'Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(1, 1, 5, 4)
|
||||
);
|
||||
|
||||
testShiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'My Second Line',
|
||||
'Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(1, 1, 5, 4),
|
||||
[
|
||||
'\tMy First Line',
|
||||
'\tMy Second Line',
|
||||
'\tThird Line',
|
||||
'',
|
||||
'\t123'
|
||||
],
|
||||
new Selection(1, 1, 5, 5)
|
||||
);
|
||||
});
|
||||
|
||||
test('Bug 9119: Unshift from first column doesn\'t work', () => {
|
||||
testUnshiftCommand(
|
||||
[
|
||||
'My First Line',
|
||||
'\t\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
null,
|
||||
true,
|
||||
new Selection(2, 1, 2, 1),
|
||||
[
|
||||
'My First Line',
|
||||
'\tMy Second Line',
|
||||
' Third Line',
|
||||
'',
|
||||
'123'
|
||||
],
|
||||
new Selection(2, 1, 2, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #348: indenting around doc block comments', () => {
|
||||
withDockBlockCommentMode((mode) => {
|
||||
|
||||
testShiftCommand(
|
||||
[
|
||||
'',
|
||||
'/**',
|
||||
' * a doc comment',
|
||||
' */',
|
||||
'function hello() {}'
|
||||
],
|
||||
mode.getLanguageIdentifier(),
|
||||
true,
|
||||
new Selection(1, 1, 5, 20),
|
||||
[
|
||||
'',
|
||||
'\t/**',
|
||||
'\t * a doc comment',
|
||||
'\t */',
|
||||
'\tfunction hello() {}'
|
||||
],
|
||||
new Selection(1, 1, 5, 21)
|
||||
);
|
||||
|
||||
testUnshiftCommand(
|
||||
[
|
||||
'',
|
||||
'/**',
|
||||
' * a doc comment',
|
||||
' */',
|
||||
'function hello() {}'
|
||||
],
|
||||
mode.getLanguageIdentifier(),
|
||||
true,
|
||||
new Selection(1, 1, 5, 20),
|
||||
[
|
||||
'',
|
||||
'/**',
|
||||
' * a doc comment',
|
||||
' */',
|
||||
'function hello() {}'
|
||||
],
|
||||
new Selection(1, 1, 5, 20)
|
||||
);
|
||||
|
||||
testUnshiftCommand(
|
||||
[
|
||||
'\t',
|
||||
'\t/**',
|
||||
'\t * a doc comment',
|
||||
'\t */',
|
||||
'\tfunction hello() {}'
|
||||
],
|
||||
mode.getLanguageIdentifier(),
|
||||
true,
|
||||
new Selection(1, 1, 5, 21),
|
||||
[
|
||||
'',
|
||||
'/**',
|
||||
' * a doc comment',
|
||||
' */',
|
||||
'function hello() {}'
|
||||
],
|
||||
new Selection(1, 1, 5, 20)
|
||||
);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
test('issue #1609: Wrong indentation of block comments', () => {
|
||||
withDockBlockCommentMode((mode) => {
|
||||
testShiftCommand(
|
||||
[
|
||||
'',
|
||||
'/**',
|
||||
' * test',
|
||||
' *',
|
||||
' * @type {number}',
|
||||
' */',
|
||||
'var foo = 0;'
|
||||
],
|
||||
mode.getLanguageIdentifier(),
|
||||
true,
|
||||
new Selection(1, 1, 7, 13),
|
||||
[
|
||||
'',
|
||||
'\t/**',
|
||||
'\t * test',
|
||||
'\t *',
|
||||
'\t * @type {number}',
|
||||
'\t */',
|
||||
'\tvar foo = 0;'
|
||||
],
|
||||
new Selection(1, 1, 7, 14)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('issue #1620: a) Line indent doesn\'t handle leading whitespace properly', () => {
|
||||
testCommand(
|
||||
[
|
||||
' Written | Numeric',
|
||||
' one | 1',
|
||||
' two | 2',
|
||||
' three | 3',
|
||||
' four | 4',
|
||||
' five | 5',
|
||||
' six | 6',
|
||||
' seven | 7',
|
||||
' eight | 8',
|
||||
' nine | 9',
|
||||
' ten | 10',
|
||||
' eleven | 11',
|
||||
'',
|
||||
],
|
||||
null,
|
||||
new Selection(1, 1, 13, 1),
|
||||
(sel) => new ShiftCommand(sel, {
|
||||
isUnshift: false,
|
||||
tabSize: 4,
|
||||
oneIndent: ' ',
|
||||
useTabStops: false
|
||||
}),
|
||||
[
|
||||
' Written | Numeric',
|
||||
' one | 1',
|
||||
' two | 2',
|
||||
' three | 3',
|
||||
' four | 4',
|
||||
' five | 5',
|
||||
' six | 6',
|
||||
' seven | 7',
|
||||
' eight | 8',
|
||||
' nine | 9',
|
||||
' ten | 10',
|
||||
' eleven | 11',
|
||||
'',
|
||||
],
|
||||
new Selection(1, 1, 13, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #1620: b) Line indent doesn\'t handle leading whitespace properly', () => {
|
||||
testCommand(
|
||||
[
|
||||
' Written | Numeric',
|
||||
' one | 1',
|
||||
' two | 2',
|
||||
' three | 3',
|
||||
' four | 4',
|
||||
' five | 5',
|
||||
' six | 6',
|
||||
' seven | 7',
|
||||
' eight | 8',
|
||||
' nine | 9',
|
||||
' ten | 10',
|
||||
' eleven | 11',
|
||||
'',
|
||||
],
|
||||
null,
|
||||
new Selection(1, 1, 13, 1),
|
||||
(sel) => new ShiftCommand(sel, {
|
||||
isUnshift: true,
|
||||
tabSize: 4,
|
||||
oneIndent: ' ',
|
||||
useTabStops: false
|
||||
}),
|
||||
[
|
||||
' Written | Numeric',
|
||||
' one | 1',
|
||||
' two | 2',
|
||||
' three | 3',
|
||||
' four | 4',
|
||||
' five | 5',
|
||||
' six | 6',
|
||||
' seven | 7',
|
||||
' eight | 8',
|
||||
' nine | 9',
|
||||
' ten | 10',
|
||||
' eleven | 11',
|
||||
'',
|
||||
],
|
||||
new Selection(1, 1, 13, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #1620: c) Line indent doesn\'t handle leading whitespace properly', () => {
|
||||
testCommand(
|
||||
[
|
||||
' Written | Numeric',
|
||||
' one | 1',
|
||||
' two | 2',
|
||||
' three | 3',
|
||||
' four | 4',
|
||||
' five | 5',
|
||||
' six | 6',
|
||||
' seven | 7',
|
||||
' eight | 8',
|
||||
' nine | 9',
|
||||
' ten | 10',
|
||||
' eleven | 11',
|
||||
'',
|
||||
],
|
||||
null,
|
||||
new Selection(1, 1, 13, 1),
|
||||
(sel) => new ShiftCommand(sel, {
|
||||
isUnshift: true,
|
||||
tabSize: 4,
|
||||
oneIndent: '\t',
|
||||
useTabStops: false
|
||||
}),
|
||||
[
|
||||
' Written | Numeric',
|
||||
' one | 1',
|
||||
' two | 2',
|
||||
' three | 3',
|
||||
' four | 4',
|
||||
' five | 5',
|
||||
' six | 6',
|
||||
' seven | 7',
|
||||
' eight | 8',
|
||||
' nine | 9',
|
||||
' ten | 10',
|
||||
' eleven | 11',
|
||||
'',
|
||||
],
|
||||
new Selection(1, 1, 13, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #1620: d) Line indent doesn\'t handle leading whitespace properly', () => {
|
||||
testCommand(
|
||||
[
|
||||
'\t Written | Numeric',
|
||||
'\t one | 1',
|
||||
'\t two | 2',
|
||||
'\t three | 3',
|
||||
'\t four | 4',
|
||||
'\t five | 5',
|
||||
'\t six | 6',
|
||||
'\t seven | 7',
|
||||
'\t eight | 8',
|
||||
'\t nine | 9',
|
||||
'\t ten | 10',
|
||||
'\t eleven | 11',
|
||||
'',
|
||||
],
|
||||
null,
|
||||
new Selection(1, 1, 13, 1),
|
||||
(sel) => new ShiftCommand(sel, {
|
||||
isUnshift: true,
|
||||
tabSize: 4,
|
||||
oneIndent: ' ',
|
||||
useTabStops: false
|
||||
}),
|
||||
[
|
||||
' Written | Numeric',
|
||||
' one | 1',
|
||||
' two | 2',
|
||||
' three | 3',
|
||||
' four | 4',
|
||||
' five | 5',
|
||||
' six | 6',
|
||||
' seven | 7',
|
||||
' eight | 8',
|
||||
' nine | 9',
|
||||
' ten | 10',
|
||||
' eleven | 11',
|
||||
'',
|
||||
],
|
||||
new Selection(1, 1, 13, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('issue Microsoft/monaco-editor#443: Indentation of a single row deletes selected text in some cases', () => {
|
||||
testCommand(
|
||||
[
|
||||
'Hello world!',
|
||||
'another line'
|
||||
],
|
||||
null,
|
||||
new Selection(1, 1, 1, 13),
|
||||
(sel) => new ShiftCommand(sel, {
|
||||
isUnshift: false,
|
||||
tabSize: 4,
|
||||
oneIndent: '\t',
|
||||
useTabStops: true
|
||||
}),
|
||||
[
|
||||
'\tHello world!',
|
||||
'another line'
|
||||
],
|
||||
new Selection(1, 1, 1, 14)
|
||||
);
|
||||
});
|
||||
|
||||
test('bug #16815:Shift+Tab doesn\'t go back to tabstop', () => {
|
||||
|
||||
var repeatStr = (str: string, cnt: number): string => {
|
||||
var r = '';
|
||||
for (var i = 0; i < cnt; i++) {
|
||||
r += str;
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
var testOutdent = (tabSize: number, oneIndent: string, lineText: string, expectedIndents: number) => {
|
||||
var expectedIndent = repeatStr(oneIndent, expectedIndents);
|
||||
if (lineText.length > 0) {
|
||||
_assertUnshiftCommand(tabSize, oneIndent, [lineText + 'aaa'], [createSingleEditOp(expectedIndent, 1, 1, 1, lineText.length + 1)]);
|
||||
} else {
|
||||
_assertUnshiftCommand(tabSize, oneIndent, [lineText + 'aaa'], []);
|
||||
}
|
||||
};
|
||||
|
||||
var testIndent = (tabSize: number, oneIndent: string, lineText: string, expectedIndents: number) => {
|
||||
var expectedIndent = repeatStr(oneIndent, expectedIndents);
|
||||
_assertShiftCommand(tabSize, oneIndent, [lineText + 'aaa'], [createSingleEditOp(expectedIndent, 1, 1, 1, lineText.length + 1)]);
|
||||
};
|
||||
|
||||
var testIndentation = (tabSize: number, lineText: string, expectedOnOutdent: number, expectedOnIndent: number) => {
|
||||
var spaceIndent = '';
|
||||
for (var i = 0; i < tabSize; i++) {
|
||||
spaceIndent += ' ';
|
||||
}
|
||||
|
||||
testOutdent(tabSize, spaceIndent, lineText, expectedOnOutdent);
|
||||
testOutdent(tabSize, '\t', lineText, expectedOnOutdent);
|
||||
|
||||
testIndent(tabSize, spaceIndent, lineText, expectedOnIndent);
|
||||
testIndent(tabSize, '\t', lineText, expectedOnIndent);
|
||||
};
|
||||
|
||||
// insertSpaces: true
|
||||
// 0 => 0
|
||||
testIndentation(4, '', 0, 1);
|
||||
|
||||
// 1 => 0
|
||||
testIndentation(4, '\t', 0, 2);
|
||||
testIndentation(4, ' ', 0, 1);
|
||||
testIndentation(4, ' \t', 0, 2);
|
||||
testIndentation(4, ' ', 0, 1);
|
||||
testIndentation(4, ' \t', 0, 2);
|
||||
testIndentation(4, ' ', 0, 1);
|
||||
testIndentation(4, ' \t', 0, 2);
|
||||
testIndentation(4, ' ', 0, 2);
|
||||
|
||||
// 2 => 1
|
||||
testIndentation(4, '\t\t', 1, 3);
|
||||
testIndentation(4, '\t ', 1, 2);
|
||||
testIndentation(4, '\t \t', 1, 3);
|
||||
testIndentation(4, '\t ', 1, 2);
|
||||
testIndentation(4, '\t \t', 1, 3);
|
||||
testIndentation(4, '\t ', 1, 2);
|
||||
testIndentation(4, '\t \t', 1, 3);
|
||||
testIndentation(4, '\t ', 1, 3);
|
||||
testIndentation(4, ' \t\t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 2);
|
||||
testIndentation(4, ' \t \t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 2);
|
||||
testIndentation(4, ' \t \t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 2);
|
||||
testIndentation(4, ' \t \t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 3);
|
||||
testIndentation(4, ' \t\t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 2);
|
||||
testIndentation(4, ' \t \t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 2);
|
||||
testIndentation(4, ' \t \t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 2);
|
||||
testIndentation(4, ' \t \t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 3);
|
||||
testIndentation(4, ' \t\t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 2);
|
||||
testIndentation(4, ' \t \t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 2);
|
||||
testIndentation(4, ' \t \t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 2);
|
||||
testIndentation(4, ' \t \t', 1, 3);
|
||||
testIndentation(4, ' \t ', 1, 3);
|
||||
testIndentation(4, ' \t', 1, 3);
|
||||
testIndentation(4, ' ', 1, 2);
|
||||
testIndentation(4, ' \t', 1, 3);
|
||||
testIndentation(4, ' ', 1, 2);
|
||||
testIndentation(4, ' \t', 1, 3);
|
||||
testIndentation(4, ' ', 1, 2);
|
||||
testIndentation(4, ' \t', 1, 3);
|
||||
testIndentation(4, ' ', 1, 3);
|
||||
|
||||
// 3 => 2
|
||||
testIndentation(4, ' ', 2, 3);
|
||||
|
||||
function _assertUnshiftCommand(tabSize: number, oneIndent: string, text: string[], expected: IIdentifiedSingleEditOperation[]): void {
|
||||
return withEditorModel(text, (model) => {
|
||||
var op = new ShiftCommand(new Selection(1, 1, text.length + 1, 1), {
|
||||
isUnshift: true,
|
||||
tabSize: tabSize,
|
||||
oneIndent: oneIndent,
|
||||
useTabStops: true
|
||||
});
|
||||
var actual = getEditOperation(model, op);
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
}
|
||||
|
||||
function _assertShiftCommand(tabSize: number, oneIndent: string, text: string[], expected: IIdentifiedSingleEditOperation[]): void {
|
||||
return withEditorModel(text, (model) => {
|
||||
var op = new ShiftCommand(new Selection(1, 1, text.length + 1, 1), {
|
||||
isUnshift: false,
|
||||
tabSize: tabSize,
|
||||
oneIndent: oneIndent,
|
||||
useTabStops: true
|
||||
});
|
||||
var actual = getEditOperation(model, op);
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,886 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { IIdentifiedSingleEditOperation } from 'vs/editor/common/editorCommon';
|
||||
import { withMockCodeEditor } from 'vs/editor/test/common/mocks/mockCodeEditor';
|
||||
import { Model } from 'vs/editor/common/model/model';
|
||||
import { TestConfiguration } from 'vs/editor/test/common/mocks/testConfiguration';
|
||||
import { ViewModel } from 'vs/editor/common/viewModel/viewModelImpl';
|
||||
import { Cursor } from 'vs/editor/common/controller/cursor';
|
||||
|
||||
function testCommand(lines: string[], selections: Selection[], edits: IIdentifiedSingleEditOperation[], expectedLines: string[], expectedSelections: Selection[]): void {
|
||||
withMockCodeEditor(lines, {}, (editor, cursor) => {
|
||||
const model = editor.getModel();
|
||||
|
||||
cursor.setSelections('tests', selections);
|
||||
|
||||
model.applyEdits(edits);
|
||||
|
||||
assert.deepEqual(model.getLinesContent(), expectedLines);
|
||||
|
||||
let actualSelections = cursor.getSelections();
|
||||
assert.deepEqual(actualSelections.map(s => s.toString()), expectedSelections.map(s => s.toString()));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
suite('Editor Side Editing - collapsed selection', () => {
|
||||
|
||||
test('replace at selection', () => {
|
||||
testCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth'
|
||||
],
|
||||
[new Selection(1, 1, 1, 1)],
|
||||
[
|
||||
EditOperation.replace(new Selection(1, 1, 1, 1), 'something ')
|
||||
],
|
||||
[
|
||||
'something first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth'
|
||||
],
|
||||
[new Selection(1, 1, 1, 11)]
|
||||
);
|
||||
});
|
||||
|
||||
test('replace at selection 2', () => {
|
||||
testCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth'
|
||||
],
|
||||
[new Selection(1, 1, 1, 6)],
|
||||
[
|
||||
EditOperation.replace(new Selection(1, 1, 1, 6), 'something')
|
||||
],
|
||||
[
|
||||
'something',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth'
|
||||
],
|
||||
[new Selection(1, 1, 1, 10)]
|
||||
);
|
||||
});
|
||||
|
||||
test('insert at selection', () => {
|
||||
testCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth'
|
||||
],
|
||||
[new Selection(1, 1, 1, 1)],
|
||||
[
|
||||
EditOperation.insert(new Position(1, 1), 'something ')
|
||||
],
|
||||
[
|
||||
'something first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth'
|
||||
],
|
||||
[new Selection(1, 11, 1, 11)]
|
||||
);
|
||||
});
|
||||
|
||||
test('insert at selection sitting on max column', () => {
|
||||
testCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth'
|
||||
],
|
||||
[new Selection(1, 6, 1, 6)],
|
||||
[
|
||||
EditOperation.insert(new Position(1, 6), ' something\nnew ')
|
||||
],
|
||||
[
|
||||
'first something',
|
||||
'new ',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth'
|
||||
],
|
||||
[new Selection(2, 5, 2, 5)]
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #3994: replace on top of selection', () => {
|
||||
testCommand(
|
||||
[
|
||||
'$obj = New-Object "system.col"'
|
||||
],
|
||||
[new Selection(1, 30, 1, 30)],
|
||||
[
|
||||
EditOperation.replaceMove(new Range(1, 19, 1, 31), '"System.Collections"')
|
||||
],
|
||||
[
|
||||
'$obj = New-Object "System.Collections"'
|
||||
],
|
||||
[new Selection(1, 39, 1, 39)]
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #15267: Suggestion that adds a line - cursor goes to the wrong line ', () => {
|
||||
testCommand(
|
||||
[
|
||||
'package main',
|
||||
'',
|
||||
'import (',
|
||||
' "fmt"',
|
||||
')',
|
||||
'',
|
||||
'func main(',
|
||||
' fmt.Println(strings.Con)',
|
||||
'}'
|
||||
],
|
||||
[new Selection(8, 25, 8, 25)],
|
||||
[
|
||||
EditOperation.replaceMove(new Range(5, 1, 5, 1), '\t\"strings\"\n')
|
||||
],
|
||||
[
|
||||
'package main',
|
||||
'',
|
||||
'import (',
|
||||
' "fmt"',
|
||||
' "strings"',
|
||||
')',
|
||||
'',
|
||||
'func main(',
|
||||
' fmt.Println(strings.Con)',
|
||||
'}'
|
||||
],
|
||||
[new Selection(9, 25, 9, 25)]
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #15236: Selections broke after deleting text using vscode.TextEditor.edit ', () => {
|
||||
testCommand(
|
||||
[
|
||||
'foofoofoo, foofoofoo, bar'
|
||||
],
|
||||
[new Selection(1, 1, 1, 10), new Selection(1, 12, 1, 21)],
|
||||
[
|
||||
EditOperation.replace(new Range(1, 1, 1, 10), ''),
|
||||
EditOperation.replace(new Range(1, 12, 1, 21), ''),
|
||||
],
|
||||
[
|
||||
', , bar'
|
||||
],
|
||||
[new Selection(1, 1, 1, 1), new Selection(1, 3, 1, 3)]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
suite('SideEditing', () => {
|
||||
|
||||
const LINES = [
|
||||
'My First Line',
|
||||
'My Second Line',
|
||||
'Third Line'
|
||||
];
|
||||
|
||||
function _runTest(selection: Selection, editRange: Range, editText: string, editForceMoveMarkers: boolean, expected: Selection, msg: string): void {
|
||||
const model = Model.createFromString(LINES.join('\n'));
|
||||
const config = new TestConfiguration(null);
|
||||
const viewModel = new ViewModel(0, config, model, null);
|
||||
const cursor = new Cursor(config, model, viewModel);
|
||||
|
||||
cursor.setSelections('tests', [selection]);
|
||||
model.applyEdits([{ range: editRange, text: editText, forceMoveMarkers: editForceMoveMarkers, identifier: null }]);
|
||||
const actual = cursor.getSelection();
|
||||
assert.deepEqual(actual.toString(), expected.toString(), msg);
|
||||
|
||||
cursor.dispose();
|
||||
viewModel.dispose();
|
||||
config.dispose();
|
||||
model.dispose();
|
||||
}
|
||||
|
||||
function runTest(selection: Range, editRange: Range, editText: string, expected: Selection[][]): void {
|
||||
const sel1 = new Selection(selection.startLineNumber, selection.startColumn, selection.endLineNumber, selection.endColumn);
|
||||
_runTest(sel1, editRange, editText, false, expected[0][0], '0-0-regular-no-force');
|
||||
_runTest(sel1, editRange, editText, true, expected[1][0], '1-0-regular-force');
|
||||
|
||||
// RTL selection
|
||||
const sel2 = new Selection(selection.endLineNumber, selection.endColumn, selection.startLineNumber, selection.startColumn);
|
||||
_runTest(sel2, editRange, editText, false, expected[0][1], '0-1-inverse-no-force');
|
||||
_runTest(sel2, editRange, editText, true, expected[1][1], '1-1-inverse-force');
|
||||
}
|
||||
|
||||
suite('insert', () => {
|
||||
suite('collapsed sel', () => {
|
||||
test('before', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 3, 1, 3), 'xx',
|
||||
[
|
||||
[new Selection(1, 6, 1, 6), new Selection(1, 6, 1, 6)],
|
||||
[new Selection(1, 6, 1, 6), new Selection(1, 6, 1, 6)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('equal', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 4, 1, 4), 'xx',
|
||||
[
|
||||
[new Selection(1, 4, 1, 6), new Selection(1, 4, 1, 6)],
|
||||
[new Selection(1, 6, 1, 6), new Selection(1, 6, 1, 6)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('after', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 5, 1, 5), 'xx',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
suite('non-collapsed dec', () => {
|
||||
test('before', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 3), 'xx',
|
||||
[
|
||||
[new Selection(1, 6, 1, 11), new Selection(1, 11, 1, 6)],
|
||||
[new Selection(1, 6, 1, 11), new Selection(1, 11, 1, 6)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 4), 'xx',
|
||||
[
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
[new Selection(1, 6, 1, 11), new Selection(1, 11, 1, 6)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('inside', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 5), 'xx',
|
||||
[
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 9, 1, 9), 'xx',
|
||||
[
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('after', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 10, 1, 10), 'xx',
|
||||
[
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('delete', () => {
|
||||
suite('collapsed dec', () => {
|
||||
test('edit.end < range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 1, 1, 3), '',
|
||||
[
|
||||
[new Selection(1, 2, 1, 2), new Selection(1, 2, 1, 2)],
|
||||
[new Selection(1, 2, 1, 2), new Selection(1, 2, 1, 2)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.end <= range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 2, 1, 4), '',
|
||||
[
|
||||
[new Selection(1, 2, 1, 2), new Selection(1, 2, 1, 2)],
|
||||
[new Selection(1, 2, 1, 2), new Selection(1, 2, 1, 2)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 3, 1, 5), '',
|
||||
[
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start >= range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 4, 1, 6), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 5, 1, 7), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
suite('non-collapsed dec', () => {
|
||||
test('edit.end < range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 1, 1, 3), '',
|
||||
[
|
||||
[new Selection(1, 2, 1, 7), new Selection(1, 7, 1, 2)],
|
||||
[new Selection(1, 2, 1, 7), new Selection(1, 7, 1, 2)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.end <= range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 2, 1, 4), '',
|
||||
[
|
||||
[new Selection(1, 2, 1, 7), new Selection(1, 7, 1, 2)],
|
||||
[new Selection(1, 2, 1, 7), new Selection(1, 7, 1, 2)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end < range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 5), '',
|
||||
[
|
||||
[new Selection(1, 3, 1, 7), new Selection(1, 7, 1, 3)],
|
||||
[new Selection(1, 3, 1, 7), new Selection(1, 7, 1, 3)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start < range.start && edit.end == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 9), '',
|
||||
[
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start < range.start && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 10), '',
|
||||
[
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start == range.start && edit.end < range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 6), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 7), new Selection(1, 7, 1, 4)],
|
||||
[new Selection(1, 4, 1, 7), new Selection(1, 7, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start == range.start && edit.end == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 9), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start == range.start && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 10), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start > range.start && edit.start < range.end && edit.end < range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 7), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 7), new Selection(1, 7, 1, 4)],
|
||||
[new Selection(1, 4, 1, 7), new Selection(1, 7, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start > range.start && edit.start < range.end && edit.end == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 9), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 5), new Selection(1, 5, 1, 4)],
|
||||
[new Selection(1, 4, 1, 5), new Selection(1, 5, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start > range.start && edit.start < range.end && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 10), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 5), new Selection(1, 5, 1, 4)],
|
||||
[new Selection(1, 4, 1, 5), new Selection(1, 5, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 9, 1, 11), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('edit.start > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 10, 1, 11), '',
|
||||
[
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('replace short', () => {
|
||||
suite('collapsed dec', () => {
|
||||
test('edit.end < range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 1, 1, 3), 'c',
|
||||
[
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.end <= range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 2, 1, 4), 'c',
|
||||
[
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
[new Selection(1, 3, 1, 3), new Selection(1, 3, 1, 3)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 3, 1, 5), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start >= range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 4, 1, 6), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 5, 1, 5), new Selection(1, 5, 1, 5)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 5, 1, 7), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
suite('non-collapsed dec', () => {
|
||||
test('edit.end < range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 1, 1, 3), 'c',
|
||||
[
|
||||
[new Selection(1, 3, 1, 8), new Selection(1, 8, 1, 3)],
|
||||
[new Selection(1, 3, 1, 8), new Selection(1, 8, 1, 3)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.end <= range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 2, 1, 4), 'c',
|
||||
[
|
||||
[new Selection(1, 3, 1, 8), new Selection(1, 8, 1, 3)],
|
||||
[new Selection(1, 3, 1, 8), new Selection(1, 8, 1, 3)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end < range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 5), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 8), new Selection(1, 8, 1, 4)],
|
||||
[new Selection(1, 4, 1, 8), new Selection(1, 8, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 9), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 10), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start == range.start && edit.end < range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 6), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 8), new Selection(1, 8, 1, 4)],
|
||||
[new Selection(1, 5, 1, 8), new Selection(1, 8, 1, 5)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start == range.start && edit.end == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 9), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 5), new Selection(1, 5, 1, 4)],
|
||||
[new Selection(1, 5, 1, 5), new Selection(1, 5, 1, 5)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start == range.start && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 10), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 5), new Selection(1, 5, 1, 4)],
|
||||
[new Selection(1, 5, 1, 5), new Selection(1, 5, 1, 5)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.start && edit.start < range.end && edit.end < range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 7), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 8), new Selection(1, 8, 1, 4)],
|
||||
[new Selection(1, 4, 1, 8), new Selection(1, 8, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.start && edit.start < range.end && edit.end == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 9), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 6), new Selection(1, 6, 1, 4)],
|
||||
[new Selection(1, 4, 1, 6), new Selection(1, 6, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.start && edit.start < range.end && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 10), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 6), new Selection(1, 6, 1, 4)],
|
||||
[new Selection(1, 4, 1, 6), new Selection(1, 6, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 9, 1, 11), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
[new Selection(1, 4, 1, 10), new Selection(1, 10, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 10, 1, 11), 'c',
|
||||
[
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('replace long', () => {
|
||||
suite('collapsed dec', () => {
|
||||
test('edit.end < range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 1, 1, 3), 'cccc',
|
||||
[
|
||||
[new Selection(1, 6, 1, 6), new Selection(1, 6, 1, 6)],
|
||||
[new Selection(1, 6, 1, 6), new Selection(1, 6, 1, 6)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.end <= range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 2, 1, 4), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 6), new Selection(1, 4, 1, 6)],
|
||||
[new Selection(1, 6, 1, 6), new Selection(1, 6, 1, 6)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 3, 1, 5), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 7, 1, 7), new Selection(1, 7, 1, 7)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start >= range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 4, 1, 6), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 8, 1, 8), new Selection(1, 8, 1, 8)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 4),
|
||||
new Range(1, 5, 1, 7), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
[new Selection(1, 4, 1, 4), new Selection(1, 4, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
suite('non-collapsed dec', () => {
|
||||
test('edit.end < range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 1, 1, 3), 'cccc',
|
||||
[
|
||||
[new Selection(1, 6, 1, 11), new Selection(1, 11, 1, 6)],
|
||||
[new Selection(1, 6, 1, 11), new Selection(1, 11, 1, 6)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.end <= range.start', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 2, 1, 4), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
[new Selection(1, 6, 1, 11), new Selection(1, 11, 1, 6)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end < range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 5), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
[new Selection(1, 7, 1, 11), new Selection(1, 11, 1, 7)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 9), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 7), new Selection(1, 7, 1, 4)],
|
||||
[new Selection(1, 7, 1, 7), new Selection(1, 7, 1, 7)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start < range.start && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 3, 1, 10), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 7), new Selection(1, 7, 1, 4)],
|
||||
[new Selection(1, 7, 1, 7), new Selection(1, 7, 1, 7)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start == range.start && edit.end < range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 6), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
[new Selection(1, 8, 1, 11), new Selection(1, 11, 1, 8)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start == range.start && edit.end == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 9), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 8), new Selection(1, 8, 1, 4)],
|
||||
[new Selection(1, 8, 1, 8), new Selection(1, 8, 1, 8)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start == range.start && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 4, 1, 10), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 8), new Selection(1, 8, 1, 4)],
|
||||
[new Selection(1, 8, 1, 8), new Selection(1, 8, 1, 8)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.start && edit.start < range.end && edit.end < range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 7), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
[new Selection(1, 4, 1, 11), new Selection(1, 11, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.start && edit.start < range.end && edit.end == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 9), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.start && edit.start < range.end && edit.end > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 5, 1, 10), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start == range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 9, 1, 11), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
[new Selection(1, 4, 1, 13), new Selection(1, 13, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
test('edit.start > range.end', () => {
|
||||
runTest(
|
||||
new Range(1, 4, 1, 9),
|
||||
new Range(1, 10, 1, 11), 'cccc',
|
||||
[
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
[new Selection(1, 4, 1, 9), new Selection(1, 9, 1, 4)],
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,82 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { TrimTrailingWhitespaceCommand, trimTrailingWhitespace } from 'vs/editor/common/commands/trimTrailingWhitespaceCommand';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IIdentifiedSingleEditOperation } from 'vs/editor/common/editorCommon';
|
||||
import { createInsertDeleteSingleEditOp, createSingleEditOp, getEditOperation } from 'vs/editor/test/common/commands/commandTestUtils';
|
||||
import { withEditorModel } from 'vs/editor/test/common/editorTestUtils';
|
||||
|
||||
function assertTrimTrailingWhitespaceCommand(text: string[], expected: IIdentifiedSingleEditOperation[]): void {
|
||||
return withEditorModel(text, (model) => {
|
||||
var op = new TrimTrailingWhitespaceCommand(new Selection(1, 1, 1, 1), []);
|
||||
var actual = getEditOperation(model, op);
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
}
|
||||
|
||||
function assertTrimTrailingWhitespace(text: string[], cursors: Position[], expected: IIdentifiedSingleEditOperation[]): void {
|
||||
return withEditorModel(text, (model) => {
|
||||
var actual = trimTrailingWhitespace(model, cursors);
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
}
|
||||
|
||||
suite('Editor Commands - Trim Trailing Whitespace Command', () => {
|
||||
|
||||
test('remove trailing whitespace', function () {
|
||||
assertTrimTrailingWhitespaceCommand([''], []);
|
||||
assertTrimTrailingWhitespaceCommand(['text'], []);
|
||||
assertTrimTrailingWhitespaceCommand(['text '], [createSingleEditOp(null, 1, 5, 1, 8)]);
|
||||
assertTrimTrailingWhitespaceCommand(['text\t '], [createSingleEditOp(null, 1, 5, 1, 9)]);
|
||||
assertTrimTrailingWhitespaceCommand(['\t '], [createSingleEditOp(null, 1, 1, 1, 5)]);
|
||||
assertTrimTrailingWhitespaceCommand(['text\t'], [createSingleEditOp(null, 1, 5, 1, 6)]);
|
||||
assertTrimTrailingWhitespaceCommand([
|
||||
'some text\t',
|
||||
'some more text',
|
||||
'\t ',
|
||||
'even more text ',
|
||||
'and some mixed\t \t'
|
||||
], [
|
||||
createSingleEditOp(null, 1, 10, 1, 11),
|
||||
createSingleEditOp(null, 3, 1, 3, 4),
|
||||
createSingleEditOp(null, 4, 15, 4, 17),
|
||||
createSingleEditOp(null, 5, 15, 5, 20)
|
||||
]);
|
||||
|
||||
|
||||
assertTrimTrailingWhitespace(['text '], [new Position(1, 1), new Position(1, 2), new Position(1, 3)], [createInsertDeleteSingleEditOp(null, 1, 5, 1, 8)]);
|
||||
assertTrimTrailingWhitespace(['text '], [new Position(1, 1), new Position(1, 5)], [createInsertDeleteSingleEditOp(null, 1, 5, 1, 8)]);
|
||||
assertTrimTrailingWhitespace(['text '], [new Position(1, 1), new Position(1, 5), new Position(1, 6)], [createInsertDeleteSingleEditOp(null, 1, 6, 1, 8)]);
|
||||
assertTrimTrailingWhitespace([
|
||||
'some text\t',
|
||||
'some more text',
|
||||
'\t ',
|
||||
'even more text ',
|
||||
'and some mixed\t \t'
|
||||
], [], [
|
||||
createInsertDeleteSingleEditOp(null, 1, 10, 1, 11),
|
||||
createInsertDeleteSingleEditOp(null, 3, 1, 3, 4),
|
||||
createInsertDeleteSingleEditOp(null, 4, 15, 4, 17),
|
||||
createInsertDeleteSingleEditOp(null, 5, 15, 5, 20)
|
||||
]);
|
||||
assertTrimTrailingWhitespace([
|
||||
'some text\t',
|
||||
'some more text',
|
||||
'\t ',
|
||||
'even more text ',
|
||||
'and some mixed\t \t'
|
||||
], [new Position(1, 11), new Position(3, 2), new Position(5, 1), new Position(4, 1), new Position(5, 10)], [
|
||||
createInsertDeleteSingleEditOp(null, 3, 2, 3, 4),
|
||||
createInsertDeleteSingleEditOp(null, 4, 15, 4, 17),
|
||||
createInsertDeleteSingleEditOp(null, 5, 15, 5, 20)
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@ import { LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
import { MockMode } from 'vs/editor/test/common/mocks/mockMode';
|
||||
|
||||
export class CommentMode extends MockMode {
|
||||
private static _id = new LanguageIdentifier('commentMode', 3);
|
||||
private static readonly _id = new LanguageIdentifier('commentMode', 3);
|
||||
|
||||
constructor(commentsConfig: CommentRule) {
|
||||
super(CommentMode._id);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,512 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { Cursor } from 'vs/editor/common/controller/cursor';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Model } from 'vs/editor/common/model/model';
|
||||
import { TestConfiguration } from 'vs/editor/test/common/mocks/testConfiguration';
|
||||
import { CursorMove } from 'vs/editor/common/controller/cursorMoveCommands';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { CoreNavigationCommands } from 'vs/editor/common/controller/coreCommands';
|
||||
import { ViewModel } from 'vs/editor/common/viewModel/viewModelImpl';
|
||||
|
||||
suite('Cursor move command test', () => {
|
||||
|
||||
let thisModel: Model;
|
||||
let thisConfiguration: TestConfiguration;
|
||||
let thisViewModel: ViewModel;
|
||||
let thisCursor: Cursor;
|
||||
|
||||
setup(() => {
|
||||
let text = [
|
||||
' \tMy First Line\t ',
|
||||
'\tMy Second Line',
|
||||
' Third Line🐶',
|
||||
'',
|
||||
'1'
|
||||
].join('\n');
|
||||
|
||||
thisModel = Model.createFromString(text);
|
||||
thisConfiguration = new TestConfiguration(null);
|
||||
thisViewModel = new ViewModel(0, thisConfiguration, thisModel, null);
|
||||
thisCursor = new Cursor(thisConfiguration, thisModel, thisViewModel);
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
thisCursor.dispose();
|
||||
thisViewModel.dispose();
|
||||
thisModel.dispose();
|
||||
thisConfiguration.dispose();
|
||||
});
|
||||
|
||||
test('move left should move to left character', () => {
|
||||
moveTo(thisCursor, 1, 8);
|
||||
|
||||
moveLeft(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 7);
|
||||
});
|
||||
|
||||
test('move left should move to left by n characters', () => {
|
||||
moveTo(thisCursor, 1, 8);
|
||||
|
||||
moveLeft(thisCursor, 3);
|
||||
|
||||
cursorEqual(thisCursor, 1, 5);
|
||||
});
|
||||
|
||||
test('move left should move to left by half line', () => {
|
||||
moveTo(thisCursor, 1, 8);
|
||||
|
||||
moveLeft(thisCursor, 1, CursorMove.RawUnit.HalfLine);
|
||||
|
||||
cursorEqual(thisCursor, 1, 1);
|
||||
});
|
||||
|
||||
test('move left moves to previous line', () => {
|
||||
moveTo(thisCursor, 2, 3);
|
||||
|
||||
moveLeft(thisCursor, 10);
|
||||
|
||||
cursorEqual(thisCursor, 1, 21);
|
||||
});
|
||||
|
||||
test('move right should move to right character', () => {
|
||||
moveTo(thisCursor, 1, 5);
|
||||
|
||||
moveRight(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 6);
|
||||
});
|
||||
|
||||
test('move right should move to right by n characters', () => {
|
||||
moveTo(thisCursor, 1, 2);
|
||||
|
||||
moveRight(thisCursor, 6);
|
||||
|
||||
cursorEqual(thisCursor, 1, 8);
|
||||
});
|
||||
|
||||
test('move right should move to right by half line', () => {
|
||||
moveTo(thisCursor, 1, 4);
|
||||
|
||||
moveRight(thisCursor, 1, CursorMove.RawUnit.HalfLine);
|
||||
|
||||
cursorEqual(thisCursor, 1, 14);
|
||||
});
|
||||
|
||||
test('move right moves to next line', () => {
|
||||
moveTo(thisCursor, 1, 8);
|
||||
|
||||
moveRight(thisCursor, 100);
|
||||
|
||||
cursorEqual(thisCursor, 2, 1);
|
||||
});
|
||||
|
||||
test('move to first character of line from middle', () => {
|
||||
moveTo(thisCursor, 1, 8);
|
||||
moveToLineStart(thisCursor);
|
||||
cursorEqual(thisCursor, 1, 1);
|
||||
});
|
||||
|
||||
test('move to first character of line from first non white space character', () => {
|
||||
moveTo(thisCursor, 1, 6);
|
||||
|
||||
moveToLineStart(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 1);
|
||||
});
|
||||
|
||||
test('move to first character of line from first character', () => {
|
||||
moveTo(thisCursor, 1, 1);
|
||||
|
||||
moveToLineStart(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 1);
|
||||
});
|
||||
|
||||
test('move to first non white space character of line from middle', () => {
|
||||
moveTo(thisCursor, 1, 8);
|
||||
|
||||
moveToLineFirstNonWhiteSpaceCharacter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 6);
|
||||
});
|
||||
|
||||
test('move to first non white space character of line from first non white space character', () => {
|
||||
moveTo(thisCursor, 1, 6);
|
||||
|
||||
moveToLineFirstNonWhiteSpaceCharacter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 6);
|
||||
});
|
||||
|
||||
test('move to first non white space character of line from first character', () => {
|
||||
moveTo(thisCursor, 1, 1);
|
||||
|
||||
moveToLineFirstNonWhiteSpaceCharacter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 6);
|
||||
});
|
||||
|
||||
test('move to end of line from middle', () => {
|
||||
moveTo(thisCursor, 1, 8);
|
||||
|
||||
moveToLineEnd(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 21);
|
||||
});
|
||||
|
||||
test('move to end of line from last non white space character', () => {
|
||||
moveTo(thisCursor, 1, 19);
|
||||
|
||||
moveToLineEnd(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 21);
|
||||
});
|
||||
|
||||
test('move to end of line from line end', () => {
|
||||
moveTo(thisCursor, 1, 21);
|
||||
|
||||
moveToLineEnd(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 21);
|
||||
});
|
||||
|
||||
test('move to last non white space character from middle', () => {
|
||||
moveTo(thisCursor, 1, 8);
|
||||
|
||||
moveToLineLastNonWhiteSpaceCharacter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 19);
|
||||
});
|
||||
|
||||
test('move to last non white space character from last non white space character', () => {
|
||||
moveTo(thisCursor, 1, 19);
|
||||
|
||||
moveToLineLastNonWhiteSpaceCharacter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 19);
|
||||
});
|
||||
|
||||
test('move to last non white space character from line end', () => {
|
||||
moveTo(thisCursor, 1, 21);
|
||||
|
||||
moveToLineLastNonWhiteSpaceCharacter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 19);
|
||||
});
|
||||
|
||||
test('move to center of line not from center', () => {
|
||||
moveTo(thisCursor, 1, 8);
|
||||
|
||||
moveToLineCenter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 11);
|
||||
});
|
||||
|
||||
test('move to center of line from center', () => {
|
||||
moveTo(thisCursor, 1, 11);
|
||||
|
||||
moveToLineCenter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 11);
|
||||
});
|
||||
|
||||
test('move to center of line from start', () => {
|
||||
moveToLineStart(thisCursor);
|
||||
|
||||
moveToLineCenter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 11);
|
||||
});
|
||||
|
||||
test('move to center of line from end', () => {
|
||||
moveToLineEnd(thisCursor);
|
||||
|
||||
moveToLineCenter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 11);
|
||||
});
|
||||
|
||||
test('move up by cursor move command', () => {
|
||||
|
||||
moveTo(thisCursor, 3, 5);
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
|
||||
moveUp(thisCursor, 2);
|
||||
cursorEqual(thisCursor, 1, 5);
|
||||
|
||||
moveUp(thisCursor, 1);
|
||||
cursorEqual(thisCursor, 1, 1);
|
||||
});
|
||||
|
||||
test('move up by model line cursor move command', () => {
|
||||
|
||||
moveTo(thisCursor, 3, 5);
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
|
||||
moveUpByModelLine(thisCursor, 2);
|
||||
cursorEqual(thisCursor, 1, 5);
|
||||
|
||||
moveUpByModelLine(thisCursor, 1);
|
||||
cursorEqual(thisCursor, 1, 1);
|
||||
});
|
||||
|
||||
test('move down by model line cursor move command', () => {
|
||||
|
||||
moveTo(thisCursor, 3, 5);
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
|
||||
moveDownByModelLine(thisCursor, 2);
|
||||
cursorEqual(thisCursor, 5, 2);
|
||||
|
||||
moveDownByModelLine(thisCursor, 1);
|
||||
cursorEqual(thisCursor, 5, 2);
|
||||
});
|
||||
|
||||
test('move up with selection by cursor move command', () => {
|
||||
|
||||
moveTo(thisCursor, 3, 5);
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
|
||||
moveUp(thisCursor, 1, true);
|
||||
cursorEqual(thisCursor, 2, 2, 3, 5);
|
||||
|
||||
moveUp(thisCursor, 1, true);
|
||||
cursorEqual(thisCursor, 1, 5, 3, 5);
|
||||
});
|
||||
|
||||
test('move up and down with tabs by cursor move command', () => {
|
||||
|
||||
moveTo(thisCursor, 1, 5);
|
||||
cursorEqual(thisCursor, 1, 5);
|
||||
|
||||
moveDown(thisCursor, 4);
|
||||
cursorEqual(thisCursor, 5, 2);
|
||||
|
||||
moveUp(thisCursor, 1);
|
||||
cursorEqual(thisCursor, 4, 1);
|
||||
|
||||
moveUp(thisCursor, 1);
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
|
||||
moveUp(thisCursor, 1);
|
||||
cursorEqual(thisCursor, 2, 2);
|
||||
|
||||
moveUp(thisCursor, 1);
|
||||
cursorEqual(thisCursor, 1, 5);
|
||||
});
|
||||
|
||||
test('move up and down with end of lines starting from a long one by cursor move command', () => {
|
||||
|
||||
moveToEndOfLine(thisCursor);
|
||||
cursorEqual(thisCursor, 1, 21);
|
||||
|
||||
moveToEndOfLine(thisCursor);
|
||||
cursorEqual(thisCursor, 1, 21);
|
||||
|
||||
moveDown(thisCursor, 2);
|
||||
cursorEqual(thisCursor, 3, 17);
|
||||
|
||||
moveDown(thisCursor, 1);
|
||||
cursorEqual(thisCursor, 4, 1);
|
||||
|
||||
moveDown(thisCursor, 1);
|
||||
cursorEqual(thisCursor, 5, 2);
|
||||
|
||||
moveUp(thisCursor, 4);
|
||||
cursorEqual(thisCursor, 1, 21);
|
||||
});
|
||||
|
||||
test('move to view top line moves to first visible line if it is first line', () => {
|
||||
thisViewModel.getCompletelyVisibleViewRange = () => new Range(1, 1, 10, 1);
|
||||
|
||||
moveTo(thisCursor, 2, 2);
|
||||
moveToTop(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 1, 6);
|
||||
});
|
||||
|
||||
test('move to view top line moves to top visible line when first line is not visible', () => {
|
||||
thisViewModel.getCompletelyVisibleViewRange = () => new Range(2, 1, 10, 1);
|
||||
|
||||
moveTo(thisCursor, 4, 1);
|
||||
moveToTop(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 2, 2);
|
||||
});
|
||||
|
||||
test('move to view top line moves to nth line from top', () => {
|
||||
thisViewModel.getCompletelyVisibleViewRange = () => new Range(1, 1, 10, 1);
|
||||
|
||||
moveTo(thisCursor, 4, 1);
|
||||
moveToTop(thisCursor, 3);
|
||||
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
});
|
||||
|
||||
test('move to view top line moves to last line if n is greater than last visible line number', () => {
|
||||
thisViewModel.getCompletelyVisibleViewRange = () => new Range(1, 1, 3, 1);
|
||||
|
||||
moveTo(thisCursor, 2, 2);
|
||||
moveToTop(thisCursor, 4);
|
||||
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
});
|
||||
|
||||
test('move to view center line moves to the center line', () => {
|
||||
thisViewModel.getCompletelyVisibleViewRange = () => new Range(3, 1, 3, 1);
|
||||
|
||||
moveTo(thisCursor, 2, 2);
|
||||
moveToCenter(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
});
|
||||
|
||||
test('move to view bottom line moves to last visible line if it is last line', () => {
|
||||
thisViewModel.getCompletelyVisibleViewRange = () => new Range(1, 1, 5, 1);
|
||||
|
||||
moveTo(thisCursor, 2, 2);
|
||||
moveToBottom(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 5, 1);
|
||||
});
|
||||
|
||||
test('move to view bottom line moves to last visible line when last line is not visible', () => {
|
||||
thisViewModel.getCompletelyVisibleViewRange = () => new Range(2, 1, 3, 1);
|
||||
|
||||
moveTo(thisCursor, 2, 2);
|
||||
moveToBottom(thisCursor);
|
||||
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
});
|
||||
|
||||
test('move to view bottom line moves to nth line from bottom', () => {
|
||||
thisViewModel.getCompletelyVisibleViewRange = () => new Range(1, 1, 5, 1);
|
||||
|
||||
moveTo(thisCursor, 4, 1);
|
||||
moveToBottom(thisCursor, 3);
|
||||
|
||||
cursorEqual(thisCursor, 3, 5);
|
||||
});
|
||||
|
||||
test('move to view bottom line moves to first line if n is lesser than first visible line number', () => {
|
||||
thisViewModel.getCompletelyVisibleViewRange = () => new Range(2, 1, 5, 1);
|
||||
|
||||
moveTo(thisCursor, 4, 1);
|
||||
moveToBottom(thisCursor, 5);
|
||||
|
||||
cursorEqual(thisCursor, 2, 2);
|
||||
});
|
||||
});
|
||||
|
||||
// Move command
|
||||
|
||||
function move(cursor: Cursor, args: any) {
|
||||
CoreNavigationCommands.CursorMove.runCoreEditorCommand(cursor, args);
|
||||
}
|
||||
|
||||
function moveToLineStart(cursor: Cursor) {
|
||||
move(cursor, { to: CursorMove.RawDirection.WrappedLineStart });
|
||||
}
|
||||
|
||||
function moveToLineFirstNonWhiteSpaceCharacter(cursor: Cursor) {
|
||||
move(cursor, { to: CursorMove.RawDirection.WrappedLineFirstNonWhitespaceCharacter });
|
||||
}
|
||||
|
||||
function moveToLineCenter(cursor: Cursor) {
|
||||
move(cursor, { to: CursorMove.RawDirection.WrappedLineColumnCenter });
|
||||
}
|
||||
|
||||
function moveToLineEnd(cursor: Cursor) {
|
||||
move(cursor, { to: CursorMove.RawDirection.WrappedLineEnd });
|
||||
}
|
||||
|
||||
function moveToLineLastNonWhiteSpaceCharacter(cursor: Cursor) {
|
||||
move(cursor, { to: CursorMove.RawDirection.WrappedLineLastNonWhitespaceCharacter });
|
||||
}
|
||||
|
||||
function moveLeft(cursor: Cursor, value?: number, by?: string, select?: boolean) {
|
||||
move(cursor, { to: CursorMove.RawDirection.Left, by: by, value: value, select: select });
|
||||
}
|
||||
|
||||
function moveRight(cursor: Cursor, value?: number, by?: string, select?: boolean) {
|
||||
move(cursor, { to: CursorMove.RawDirection.Right, by: by, value: value, select: select });
|
||||
}
|
||||
|
||||
function moveUp(cursor: Cursor, noOfLines: number = 1, select?: boolean) {
|
||||
move(cursor, { to: CursorMove.RawDirection.Up, by: CursorMove.RawUnit.WrappedLine, value: noOfLines, select: select });
|
||||
}
|
||||
|
||||
function moveUpByModelLine(cursor: Cursor, noOfLines: number = 1, select?: boolean) {
|
||||
move(cursor, { to: CursorMove.RawDirection.Up, value: noOfLines, select: select });
|
||||
}
|
||||
|
||||
function moveDown(cursor: Cursor, noOfLines: number = 1, select?: boolean) {
|
||||
move(cursor, { to: CursorMove.RawDirection.Down, by: CursorMove.RawUnit.WrappedLine, value: noOfLines, select: select });
|
||||
}
|
||||
|
||||
function moveDownByModelLine(cursor: Cursor, noOfLines: number = 1, select?: boolean) {
|
||||
move(cursor, { to: CursorMove.RawDirection.Down, value: noOfLines, select: select });
|
||||
}
|
||||
|
||||
function moveToTop(cursor: Cursor, noOfLines: number = 1, select?: boolean) {
|
||||
move(cursor, { to: CursorMove.RawDirection.ViewPortTop, value: noOfLines, select: select });
|
||||
}
|
||||
|
||||
function moveToCenter(cursor: Cursor, select?: boolean) {
|
||||
move(cursor, { to: CursorMove.RawDirection.ViewPortCenter, select: select });
|
||||
}
|
||||
|
||||
function moveToBottom(cursor: Cursor, noOfLines: number = 1, select?: boolean) {
|
||||
move(cursor, { to: CursorMove.RawDirection.ViewPortBottom, value: noOfLines, select: select });
|
||||
}
|
||||
|
||||
function cursorEqual(cursor: Cursor, posLineNumber: number, posColumn: number, selLineNumber: number = posLineNumber, selColumn: number = posColumn) {
|
||||
positionEqual(cursor.getPosition(), posLineNumber, posColumn);
|
||||
selectionEqual(cursor.getSelection(), posLineNumber, posColumn, selLineNumber, selColumn);
|
||||
}
|
||||
|
||||
function positionEqual(position: Position, lineNumber: number, column: number) {
|
||||
assert.deepEqual(position, new Position(lineNumber, column), 'position equal');
|
||||
}
|
||||
|
||||
function selectionEqual(selection: Selection, posLineNumber: number, posColumn: number, selLineNumber: number, selColumn: number) {
|
||||
assert.deepEqual({
|
||||
selectionStartLineNumber: selection.selectionStartLineNumber,
|
||||
selectionStartColumn: selection.selectionStartColumn,
|
||||
positionLineNumber: selection.positionLineNumber,
|
||||
positionColumn: selection.positionColumn
|
||||
}, {
|
||||
selectionStartLineNumber: selLineNumber,
|
||||
selectionStartColumn: selColumn,
|
||||
positionLineNumber: posLineNumber,
|
||||
positionColumn: posColumn
|
||||
}, 'selection equal');
|
||||
}
|
||||
|
||||
function moveTo(cursor: Cursor, lineNumber: number, column: number, inSelectionMode: boolean = false) {
|
||||
if (inSelectionMode) {
|
||||
CoreNavigationCommands.MoveToSelect.runCoreEditorCommand(cursor, {
|
||||
position: new Position(lineNumber, column)
|
||||
});
|
||||
} else {
|
||||
CoreNavigationCommands.MoveTo.runCoreEditorCommand(cursor, {
|
||||
position: new Position(lineNumber, column)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function moveToEndOfLine(cursor: Cursor, inSelectionMode: boolean = false) {
|
||||
if (inSelectionMode) {
|
||||
CoreNavigationCommands.CursorEndSelect.runCoreEditorCommand(cursor, {});
|
||||
} else {
|
||||
CoreNavigationCommands.CursorEnd.runCoreEditorCommand(cursor, {});
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { ICommonCodeEditor, IModel } from 'vs/editor/common/editorCommon';
|
||||
import { EditorState, CodeEditorStateFlag } from 'vs/editor/common/core/editorState';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
|
||||
interface IStubEditorState {
|
||||
model?: { uri?: URI, version?: number };
|
||||
position?: Position;
|
||||
selection?: Selection;
|
||||
scroll?: { left?: number, top?: number };
|
||||
}
|
||||
|
||||
suite('Editor Core - Editor State', () => {
|
||||
|
||||
const allFlags = (
|
||||
CodeEditorStateFlag.Value
|
||||
| CodeEditorStateFlag.Selection
|
||||
| CodeEditorStateFlag.Position
|
||||
| CodeEditorStateFlag.Scroll
|
||||
);
|
||||
|
||||
test('empty editor state should be valid', () => {
|
||||
let result = validate({}, {});
|
||||
assert.equal(result, true);
|
||||
});
|
||||
|
||||
test('different model URIs should be invalid', () => {
|
||||
let result = validate(
|
||||
{ model: { uri: URI.parse('http://test1') } },
|
||||
{ model: { uri: URI.parse('http://test2') } }
|
||||
);
|
||||
|
||||
assert.equal(result, false);
|
||||
});
|
||||
|
||||
test('different model versions should be invalid', () => {
|
||||
let result = validate(
|
||||
{ model: { version: 1 } },
|
||||
{ model: { version: 2 } }
|
||||
);
|
||||
|
||||
assert.equal(result, false);
|
||||
});
|
||||
|
||||
test('different positions should be invalid', () => {
|
||||
let result = validate(
|
||||
{ position: new Position(1, 2) },
|
||||
{ position: new Position(2, 3) }
|
||||
);
|
||||
|
||||
assert.equal(result, false);
|
||||
});
|
||||
|
||||
test('different selections should be invalid', () => {
|
||||
let result = validate(
|
||||
{ selection: new Selection(1, 2, 3, 4) },
|
||||
{ selection: new Selection(5, 2, 3, 4) }
|
||||
);
|
||||
|
||||
assert.equal(result, false);
|
||||
});
|
||||
|
||||
test('different scroll positions should be invalid', () => {
|
||||
let result = validate(
|
||||
{ scroll: { left: 1, top: 2 } },
|
||||
{ scroll: { left: 3, top: 2 } }
|
||||
);
|
||||
|
||||
assert.equal(result, false);
|
||||
});
|
||||
|
||||
|
||||
function validate(source: IStubEditorState, target: IStubEditorState) {
|
||||
let sourceEditor = createEditor(source),
|
||||
targetEditor = createEditor(target);
|
||||
|
||||
let result = new EditorState(sourceEditor, allFlags).validate(targetEditor);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createEditor({ model, position, selection, scroll }: IStubEditorState = {}): ICommonCodeEditor {
|
||||
let mappedModel = model ? { uri: model.uri ? model.uri : URI.parse('http://dummy.org'), getVersionId: () => model.version } : null;
|
||||
|
||||
return <any>{
|
||||
getModel: (): IModel => <any>mappedModel,
|
||||
getPosition: (): Position => position,
|
||||
getSelection: (): Selection => selection,
|
||||
getScrollLeft: (): number => scroll && scroll.left,
|
||||
getScrollTop: (): number => scroll && scroll.top
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ suite('LineTokens', () => {
|
||||
const lineTokens = createTestLineTokens();
|
||||
|
||||
assert.equal(lineTokens.getLineContent(), 'Hello world, this is a lovely day');
|
||||
assert.equal(lineTokens.getLineLength(), 33);
|
||||
assert.equal(lineTokens.getLineContent().length, 33);
|
||||
assert.equal(lineTokens.getTokenCount(), 7);
|
||||
|
||||
assert.equal(lineTokens.getTokenStartOffset(0), 0);
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { IContextKeyService, IContextKeyServiceTarget } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
|
||||
import { CommonCodeEditor } from 'vs/editor/common/commonCodeEditor';
|
||||
import { CommonEditorConfiguration } from 'vs/editor/common/config/commonEditorConfig';
|
||||
import { Cursor } from 'vs/editor/common/controller/cursor';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { Model } from 'vs/editor/common/model/model';
|
||||
import { TestConfiguration } from 'vs/editor/test/common/mocks/testConfiguration';
|
||||
import * as editorOptions from 'vs/editor/common/config/editorOptions';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export class MockCodeEditor extends CommonCodeEditor {
|
||||
|
||||
public _isFocused = true;
|
||||
|
||||
protected _createConfiguration(options: editorOptions.IEditorOptions): CommonEditorConfiguration {
|
||||
return new TestConfiguration(options);
|
||||
}
|
||||
|
||||
public layout(dimension?: editorCommon.IDimension): void { }
|
||||
|
||||
public focus(): void { }
|
||||
public isFocused(): boolean { return this._isFocused; }
|
||||
public hasWidgetFocus(): boolean { return true; };
|
||||
|
||||
protected _enableEmptySelectionClipboard(): boolean { return false; }
|
||||
protected _scheduleAtNextAnimationFrame(callback: () => void): IDisposable { throw new Error('Notimplemented'); }
|
||||
protected _createView(): void { }
|
||||
|
||||
protected _registerDecorationType(key: string, options: editorCommon.IDecorationRenderOptions, parentTypeKey?: string): void { throw new Error('NotImplemented'); }
|
||||
protected _removeDecorationType(key: string): void { throw new Error('NotImplemented'); }
|
||||
protected _resolveDecorationOptions(typeKey: string, writable: boolean): editorCommon.IModelDecorationOptions { throw new Error('NotImplemented'); }
|
||||
|
||||
// --- test utils
|
||||
getCursor(): Cursor {
|
||||
return this.cursor;
|
||||
}
|
||||
|
||||
public registerAndInstantiateContribution<T extends editorCommon.IEditorContribution>(ctor: any): T {
|
||||
let r = <T>this._instantiationService.createInstance(ctor, this);
|
||||
this._contributions[r.getId()] = r;
|
||||
return r;
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
super.dispose();
|
||||
if (this.model) {
|
||||
this.model.dispose();
|
||||
}
|
||||
this._contextKeyService.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class MockScopeLocation implements IContextKeyServiceTarget {
|
||||
parentElement: IContextKeyServiceTarget = null;
|
||||
setAttribute(attr: string, value: string): void { }
|
||||
removeAttribute(attr: string): void { }
|
||||
hasAttribute(attr: string): boolean { return false; }
|
||||
getAttribute(attr: string): string { return undefined; }
|
||||
}
|
||||
|
||||
export interface MockCodeEditorCreationOptions extends editorOptions.IEditorOptions {
|
||||
/**
|
||||
* The initial model associated with this code editor.
|
||||
*/
|
||||
model?: editorCommon.IModel;
|
||||
serviceCollection?: ServiceCollection;
|
||||
}
|
||||
|
||||
export function withMockCodeEditor(text: string[], options: MockCodeEditorCreationOptions, callback: (editor: MockCodeEditor, cursor: Cursor) => void): void {
|
||||
// create a model if necessary and remember it in order to dispose it.
|
||||
let modelToDispose: Model = null;
|
||||
if (!options.model) {
|
||||
modelToDispose = Model.createFromString(text.join('\n'));
|
||||
options.model = modelToDispose;
|
||||
}
|
||||
|
||||
let editor = <MockCodeEditor>_mockCodeEditor(options);
|
||||
callback(editor, editor.getCursor());
|
||||
|
||||
if (modelToDispose) {
|
||||
modelToDispose.dispose();
|
||||
}
|
||||
editor.dispose();
|
||||
}
|
||||
|
||||
export function mockCodeEditor(text: string[], options: MockCodeEditorCreationOptions): CommonCodeEditor {
|
||||
// TODO: who owns this model now?
|
||||
if (!options.model) {
|
||||
options.model = Model.createFromString(text.join('\n'));
|
||||
}
|
||||
return _mockCodeEditor(options);
|
||||
}
|
||||
|
||||
function _mockCodeEditor(options: MockCodeEditorCreationOptions): CommonCodeEditor {
|
||||
|
||||
let contextKeyService = new MockContextKeyService();
|
||||
|
||||
let services = options.serviceCollection || new ServiceCollection();
|
||||
services.set(IContextKeyService, contextKeyService);
|
||||
let instantiationService = new InstantiationService(services);
|
||||
|
||||
let editor = new MockCodeEditor(new MockScopeLocation(), options, instantiationService, contextKeyService);
|
||||
editor.setModel(options.model);
|
||||
return editor;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IDecorationRenderOptions, IModelDecorationOptions } from 'vs/editor/common/editorCommon';
|
||||
import { AbstractCodeEditorService } from 'vs/editor/common/services/abstractCodeEditorService';
|
||||
|
||||
export class MockCodeEditorService extends AbstractCodeEditorService {
|
||||
public registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void { }
|
||||
public removeDecorationType(key: string): void { }
|
||||
public resolveDecorationOptions(decorationTypeKey: string, writable: boolean): IModelDecorationOptions { return null; }
|
||||
}
|
||||
@@ -12,6 +12,12 @@ import { EditableTextModel, IValidatedEditOperation } from 'vs/editor/common/mod
|
||||
import { MirrorModel } from 'vs/editor/common/model/mirrorModel';
|
||||
import { assertSyncedModels, testApplyEditsWithSyncedModels } from 'vs/editor/test/common/model/editableTextModelTestUtils';
|
||||
import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents';
|
||||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { RawTextSource } from 'vs/editor/common/model/textSource';
|
||||
|
||||
function createEditableTextModelFromString(text: string): EditableTextModel {
|
||||
return new EditableTextModel(RawTextSource.fromString(text), TextModel.DEFAULT_CREATION_OPTIONS, null);
|
||||
}
|
||||
|
||||
suite('EditorModel - EditableTextModel._getInverseEdits', () => {
|
||||
|
||||
@@ -280,7 +286,7 @@ suite('EditorModel - EditableTextModel._toSingleEditOperation', () => {
|
||||
}
|
||||
|
||||
function testSimpleApplyEdits(original: string[], edits: IValidatedEditOperation[], expected: IValidatedEditOperation): void {
|
||||
let model = EditableTextModel.createFromString(original.join('\n'));
|
||||
let model = createEditableTextModelFromString(original.join('\n'));
|
||||
model.setEOL(EndOfLineSequence.LF);
|
||||
|
||||
let actual = model._toSingleEditOperation(edits);
|
||||
@@ -522,7 +528,7 @@ suite('EditorModel - EditableTextModel._toSingleEditOperation', () => {
|
||||
suite('EditorModel - EditableTextModel.applyEdits updates mightContainRTL', () => {
|
||||
|
||||
function testApplyEdits(original: string[], edits: IIdentifiedSingleEditOperation[], before: boolean, after: boolean): void {
|
||||
let model = EditableTextModel.createFromString(original.join('\n'));
|
||||
let model = createEditableTextModelFromString(original.join('\n'));
|
||||
model.setEOL(EndOfLineSequence.LF);
|
||||
|
||||
assert.equal(model.mightContainRTL(), before);
|
||||
@@ -570,7 +576,7 @@ suite('EditorModel - EditableTextModel.applyEdits updates mightContainRTL', () =
|
||||
suite('EditorModel - EditableTextModel.applyEdits updates mightContainNonBasicASCII', () => {
|
||||
|
||||
function testApplyEdits(original: string[], edits: IIdentifiedSingleEditOperation[], before: boolean, after: boolean): void {
|
||||
let model = EditableTextModel.createFromString(original.join('\n'));
|
||||
let model = createEditableTextModelFromString(original.join('\n'));
|
||||
model.setEOL(EndOfLineSequence.LF);
|
||||
|
||||
assert.equal(model.mightContainNonBasicASCII(), before);
|
||||
@@ -1365,7 +1371,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => {
|
||||
});
|
||||
|
||||
function testApplyEditsFails(original: string[], edits: IIdentifiedSingleEditOperation[]): void {
|
||||
let model = EditableTextModel.createFromString(original.join('\n'));
|
||||
let model = createEditableTextModelFromString(original.join('\n'));
|
||||
|
||||
let hasThrown = false;
|
||||
try {
|
||||
@@ -1506,7 +1512,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => {
|
||||
|
||||
}, (model) => {
|
||||
var isFirstTime = true;
|
||||
model.addBulkListener((events) => {
|
||||
model.onDidChangeRawContent(() => {
|
||||
if (!isFirstTime) {
|
||||
return;
|
||||
}
|
||||
@@ -1553,7 +1559,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => {
|
||||
});
|
||||
|
||||
test('issue #1580: Changes in line endings are not correctly reflected in the extension host, leading to invalid offsets sent to external refactoring tools', () => {
|
||||
let model = EditableTextModel.createFromString('Hello\nWorld!');
|
||||
let model = createEditableTextModelFromString('Hello\nWorld!');
|
||||
assert.equal(model.getEOL(), '\n');
|
||||
|
||||
let mirrorModel2 = new MirrorModel(null, model.getLinesContent(), model.getEOL(), model.getVersionId());
|
||||
|
||||
@@ -1,388 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { Model } from 'vs/editor/common/model/model';
|
||||
import { computeRanges, MAX_FOLDING_REGIONS } from 'vs/editor/common/model/indentRanges';
|
||||
import { FoldingMarkers } from 'vs/editor/common/modes/languageConfiguration';
|
||||
|
||||
export interface ExpectedIndentRange {
|
||||
startLineNumber: number;
|
||||
endLineNumber: number;
|
||||
indent: number;
|
||||
parentIndex: number;
|
||||
}
|
||||
|
||||
function assertRanges(lines: string[], expected: ExpectedIndentRange[], offside: boolean, markers?: FoldingMarkers): void {
|
||||
let model = Model.createFromString(lines.join('\n'));
|
||||
let actual = computeRanges(model, offside, markers);
|
||||
|
||||
let actualRanges = [];
|
||||
for (let i = 0; i < actual.length; i++) {
|
||||
actualRanges[i] = r(actual.getStartLineNumber(i), actual.getEndLineNumber(i), actual.getIndent(i), actual.getParentIndex(i));
|
||||
}
|
||||
assert.deepEqual(actualRanges, expected);
|
||||
model.dispose();
|
||||
}
|
||||
|
||||
function r(startLineNumber: number, endLineNumber: number, indent: number, parentIndex: number, marker = false): ExpectedIndentRange {
|
||||
return { startLineNumber, endLineNumber, indent, parentIndex };
|
||||
}
|
||||
|
||||
suite('Indentation Folding', () => {
|
||||
test('Fold one level', () => {
|
||||
let range = [
|
||||
'A',
|
||||
' A',
|
||||
' A',
|
||||
' A'
|
||||
];
|
||||
assertRanges(range, [r(1, 4, 0, -1)], true);
|
||||
assertRanges(range, [r(1, 4, 0, -1)], false);
|
||||
});
|
||||
|
||||
test('Fold two levels', () => {
|
||||
let range = [
|
||||
'A',
|
||||
' A',
|
||||
' A',
|
||||
' A',
|
||||
' A'
|
||||
];
|
||||
assertRanges(range, [r(1, 5, 0, -1), r(3, 5, 2, 0)], true);
|
||||
assertRanges(range, [r(1, 5, 0, -1), r(3, 5, 2, 0)], false);
|
||||
});
|
||||
|
||||
test('Fold three levels', () => {
|
||||
let range = [
|
||||
'A',
|
||||
' A',
|
||||
' A',
|
||||
' A',
|
||||
'A'
|
||||
];
|
||||
assertRanges(range, [r(1, 4, 0, -1), r(2, 4, 2, 0), r(3, 4, 4, 1)], true);
|
||||
assertRanges(range, [r(1, 4, 0, -1), r(2, 4, 2, 0), r(3, 4, 4, 1)], false);
|
||||
});
|
||||
|
||||
test('Fold decreasing indent', () => {
|
||||
let range = [
|
||||
' A',
|
||||
' A',
|
||||
'A'
|
||||
];
|
||||
assertRanges(range, [], true);
|
||||
assertRanges(range, [], false);
|
||||
});
|
||||
|
||||
test('Fold Java', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'class A {',
|
||||
/* 2*/ ' void foo() {',
|
||||
/* 3*/ ' console.log();',
|
||||
/* 4*/ ' console.log();',
|
||||
/* 5*/ ' }',
|
||||
/* 6*/ '',
|
||||
/* 7*/ ' void bar() {',
|
||||
/* 8*/ ' console.log();',
|
||||
/* 9*/ ' }',
|
||||
/*10*/ '}',
|
||||
/*11*/ 'interface B {',
|
||||
/*12*/ ' void bar();',
|
||||
/*13*/ '}',
|
||||
], [r(1, 9, 0, -1), r(2, 4, 2, 0), r(7, 8, 2, 0), r(11, 12, 0, -1)], false);
|
||||
});
|
||||
|
||||
test('Fold Javadoc', () => {
|
||||
assertRanges([
|
||||
/* 1*/ '/**',
|
||||
/* 2*/ ' * Comment',
|
||||
/* 3*/ ' */',
|
||||
/* 4*/ 'class A {',
|
||||
/* 5*/ ' void foo() {',
|
||||
/* 6*/ ' }',
|
||||
/* 7*/ '}',
|
||||
], [r(1, 3, 0, -1), r(4, 6, 0, -1)], false);
|
||||
});
|
||||
test('Fold Whitespace Java', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'class A {',
|
||||
/* 2*/ '',
|
||||
/* 3*/ ' void foo() {',
|
||||
/* 4*/ ' ',
|
||||
/* 5*/ ' return 0;',
|
||||
/* 6*/ ' }',
|
||||
/* 7*/ ' ',
|
||||
/* 8*/ '}',
|
||||
], [r(1, 7, 0, -1), r(3, 5, 2, 0)], false);
|
||||
});
|
||||
|
||||
test('Fold Whitespace Python', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'def a:',
|
||||
/* 2*/ ' pass',
|
||||
/* 3*/ ' ',
|
||||
/* 4*/ ' def b:',
|
||||
/* 5*/ ' pass',
|
||||
/* 6*/ ' ',
|
||||
/* 7*/ ' ',
|
||||
/* 8*/ 'def c: # since there was a deintent here'
|
||||
], [r(1, 5, 0, -1), r(4, 5, 2, 0)], true);
|
||||
});
|
||||
|
||||
test('Fold Tabs', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'class A {',
|
||||
/* 2*/ '\t\t',
|
||||
/* 3*/ '\tvoid foo() {',
|
||||
/* 4*/ '\t \t//hello',
|
||||
/* 5*/ '\t return 0;',
|
||||
/* 6*/ ' \t}',
|
||||
/* 7*/ ' ',
|
||||
/* 8*/ '}',
|
||||
], [r(1, 7, 0, -1), r(3, 5, 4, 0)], false);
|
||||
});
|
||||
});
|
||||
|
||||
let markers: FoldingMarkers = {
|
||||
start: /^\s*#region\b/,
|
||||
end: /^\s*#endregion\b/
|
||||
};
|
||||
|
||||
suite('Folding with regions', () => {
|
||||
test('Inside region, indented', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'class A {',
|
||||
/* 2*/ ' #region',
|
||||
/* 3*/ ' void foo() {',
|
||||
/* 4*/ ' ',
|
||||
/* 5*/ ' return 0;',
|
||||
/* 6*/ ' }',
|
||||
/* 7*/ ' #endregion',
|
||||
/* 8*/ '}',
|
||||
], [r(1, 7, 0, -1), r(2, 7, 2, 0, true), r(3, 5, 2, 1)], false, markers);
|
||||
});
|
||||
test('Inside region, not indented', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'var x;',
|
||||
/* 2*/ '#region',
|
||||
/* 3*/ 'void foo() {',
|
||||
/* 4*/ ' ',
|
||||
/* 5*/ ' return 0;',
|
||||
/* 6*/ ' }',
|
||||
/* 7*/ '#endregion',
|
||||
/* 8*/ '',
|
||||
], [r(2, 7, 0, -1, true), r(3, 6, 0, 0)], false, markers);
|
||||
});
|
||||
test('Empty Regions', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'var x;',
|
||||
/* 2*/ '#region',
|
||||
/* 3*/ '#endregion',
|
||||
/* 4*/ '#region',
|
||||
/* 5*/ '',
|
||||
/* 6*/ '#endregion',
|
||||
/* 7*/ 'var y;',
|
||||
], [r(2, 3, 0, -1, true), r(4, 6, 0, -1, true)], false, markers);
|
||||
});
|
||||
test('Nested Regions', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'var x;',
|
||||
/* 2*/ '#region',
|
||||
/* 3*/ '#region',
|
||||
/* 4*/ '',
|
||||
/* 5*/ '#endregion',
|
||||
/* 6*/ '#endregion',
|
||||
/* 7*/ 'var y;',
|
||||
], [r(2, 6, 0, -1, true), r(3, 5, 0, 0, true)], false, markers);
|
||||
});
|
||||
test('Nested Regions 2', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'class A {',
|
||||
/* 2*/ ' #region',
|
||||
/* 3*/ '',
|
||||
/* 4*/ ' #region',
|
||||
/* 5*/ '',
|
||||
/* 6*/ ' #endregion',
|
||||
/* 7*/ ' // comment',
|
||||
/* 8*/ ' #endregion',
|
||||
/* 9*/ '}',
|
||||
], [r(1, 8, 0, -1), r(2, 8, 2, 0, true), r(4, 6, 2, 1, true)], false, markers);
|
||||
});
|
||||
test('Incomplete Regions', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'class A {',
|
||||
/* 2*/ '#region',
|
||||
/* 3*/ ' // comment',
|
||||
/* 4*/ '}',
|
||||
], [r(2, 3, 0, -1)], false, markers);
|
||||
});
|
||||
test('Incomplete Regions 2', () => {
|
||||
assertRanges([
|
||||
/* 1*/ '',
|
||||
/* 2*/ '#region',
|
||||
/* 3*/ '#region',
|
||||
/* 4*/ '#region',
|
||||
/* 5*/ ' // comment',
|
||||
/* 6*/ '#endregion',
|
||||
/* 7*/ '#endregion',
|
||||
/* 8*/ ' // hello',
|
||||
], [r(3, 7, 0, -1, true), r(4, 6, 0, 0, true)], false, markers);
|
||||
});
|
||||
test('Indented region before', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'if (x)',
|
||||
/* 2*/ ' return;',
|
||||
/* 3*/ '',
|
||||
/* 4*/ '#region',
|
||||
/* 5*/ ' // comment',
|
||||
/* 6*/ '#endregion',
|
||||
], [r(1, 3, 0, -1), r(4, 6, 0, -1, true)], false, markers);
|
||||
});
|
||||
test('Indented region before 2', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'if (x)',
|
||||
/* 2*/ ' log();',
|
||||
/* 3*/ '',
|
||||
/* 4*/ ' #region',
|
||||
/* 5*/ ' // comment',
|
||||
/* 6*/ ' #endregion',
|
||||
], [r(1, 6, 0, -1), r(2, 6, 2, 0), r(4, 6, 4, 1, true)], false, markers);
|
||||
});
|
||||
test('Indented region in-between', () => {
|
||||
assertRanges([
|
||||
/* 1*/ '#region',
|
||||
/* 2*/ ' // comment',
|
||||
/* 3*/ ' if (x)',
|
||||
/* 4*/ ' return;',
|
||||
/* 5*/ '',
|
||||
/* 6*/ '#endregion',
|
||||
], [r(1, 6, 0, -1, true), r(3, 5, 2, 0)], false, markers);
|
||||
});
|
||||
test('Indented region after', () => {
|
||||
assertRanges([
|
||||
/* 1*/ '#region',
|
||||
/* 2*/ ' // comment',
|
||||
/* 3*/ '',
|
||||
/* 4*/ '#endregion',
|
||||
/* 5*/ ' if (x)',
|
||||
/* 6*/ ' return;',
|
||||
], [r(1, 4, 0, -1, true), r(5, 6, 2, -1)], false, markers);
|
||||
});
|
||||
test('With off-side', () => {
|
||||
assertRanges([
|
||||
/* 1*/ '#region',
|
||||
/* 2*/ ' ',
|
||||
/* 3*/ '',
|
||||
/* 4*/ '#endregion',
|
||||
/* 5*/ '',
|
||||
], [r(1, 4, 0, -1, true)], true, markers);
|
||||
});
|
||||
test('Nested with off-side', () => {
|
||||
assertRanges([
|
||||
/* 1*/ '#region',
|
||||
/* 2*/ ' ',
|
||||
/* 3*/ '#region',
|
||||
/* 4*/ '',
|
||||
/* 5*/ '#endregion',
|
||||
/* 6*/ '',
|
||||
/* 7*/ '#endregion',
|
||||
/* 8*/ '',
|
||||
], [r(1, 7, 0, -1, true), r(3, 5, 0, 0, true)], true, markers);
|
||||
});
|
||||
test('Issue 35981', () => {
|
||||
assertRanges([
|
||||
/* 1*/ 'function thisFoldsToEndOfPage() {',
|
||||
/* 2*/ ' const variable = []',
|
||||
/* 3*/ ' // #region',
|
||||
/* 4*/ ' .reduce((a, b) => a,[]);',
|
||||
/* 5*/ '}',
|
||||
/* 6*/ '',
|
||||
/* 7*/ 'function thisFoldsProperly() {',
|
||||
/* 8*/ ' const foo = "bar"',
|
||||
/* 9*/ '}',
|
||||
], [r(1, 4, 0, -1), r(2, 4, 2, 0), r(7, 8, 0, -1)], false, markers);
|
||||
});
|
||||
test('Misspelled Markers', () => {
|
||||
assertRanges([
|
||||
/* 1*/ '#Region',
|
||||
/* 2*/ '#endregion',
|
||||
/* 3*/ '#regionsandmore',
|
||||
/* 4*/ '#endregion',
|
||||
/* 5*/ '#region',
|
||||
/* 6*/ '#end region',
|
||||
/* 7*/ '#region',
|
||||
/* 8*/ '#endregionff',
|
||||
], [], true, markers);
|
||||
});
|
||||
|
||||
test('test max folding regions', () => {
|
||||
let lines = [];
|
||||
let nRegions = MAX_FOLDING_REGIONS;
|
||||
for (let i = 0; i < nRegions; i++) {
|
||||
lines.push('#region');
|
||||
}
|
||||
for (let i = 0; i < nRegions; i++) {
|
||||
lines.push('#endregion');
|
||||
}
|
||||
let model = Model.createFromString(lines.join('\n'));
|
||||
let actual = computeRanges(model, false, markers, MAX_FOLDING_REGIONS);
|
||||
assert.equal(actual.length, nRegions, 'len');
|
||||
for (let i = 0; i < nRegions; i++) {
|
||||
assert.equal(actual.getStartLineNumber(i), i + 1, 'start' + i);
|
||||
assert.equal(actual.getEndLineNumber(i), nRegions * 2 - i, 'end' + i);
|
||||
assert.equal(actual.getParentIndex(i), i - 1, 'parent' + i);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
test('findRange', () => {
|
||||
let lines = [
|
||||
/* 1*/ '#region',
|
||||
/* 2*/ '#endregion',
|
||||
/* 3*/ 'class A {',
|
||||
/* 4*/ ' void foo() {',
|
||||
/* 5*/ ' if (true) {',
|
||||
/* 6*/ ' return;',
|
||||
/* 7*/ ' }',
|
||||
/* 8*/ '',
|
||||
/* 9*/ ' if (true) {',
|
||||
/* 10*/ ' return;',
|
||||
/* 11*/ ' }',
|
||||
/* 12*/ ' }',
|
||||
/* 13*/ '}'];
|
||||
|
||||
let textModel = Model.createFromString(lines.join('\n'));
|
||||
try {
|
||||
let actual = computeRanges(textModel, false, markers);
|
||||
// let r0 = r(1, 2);
|
||||
// let r1 = r(3, 12);
|
||||
// let r2 = r(4, 11);
|
||||
// let r3 = r(5, 6);
|
||||
// let r4 = r(9, 10);
|
||||
|
||||
assert.equal(actual.findRange(1), 0, '1');
|
||||
assert.equal(actual.findRange(2), 0, '2');
|
||||
assert.equal(actual.findRange(3), 1, '3');
|
||||
assert.equal(actual.findRange(4), 2, '4');
|
||||
assert.equal(actual.findRange(5), 3, '5');
|
||||
assert.equal(actual.findRange(6), 3, '6');
|
||||
assert.equal(actual.findRange(7), 2, '7');
|
||||
assert.equal(actual.findRange(8), 2, '8');
|
||||
assert.equal(actual.findRange(9), 4, '9');
|
||||
assert.equal(actual.findRange(10), 4, '10');
|
||||
assert.equal(actual.findRange(11), 2, '11');
|
||||
assert.equal(actual.findRange(12), 1, '12');
|
||||
assert.equal(actual.findRange(13), -1, '13');
|
||||
} finally {
|
||||
textModel.dispose();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -5,7 +5,7 @@
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { IntervalTree, IntervalNode } from 'vs/editor/common/model/intervalTree';
|
||||
import { IntervalTree, IntervalNode, getNodeColor, NodeColor, SENTINEL, intervalCompare } from 'vs/editor/common/model/intervalTree';
|
||||
|
||||
const GENERATE_TESTS = false;
|
||||
let TEST_COUNT = GENERATE_TESTS ? 10000 : 0;
|
||||
@@ -116,10 +116,10 @@ suite('IntervalTree', () => {
|
||||
}
|
||||
|
||||
if (PRINT_TREE) {
|
||||
this._tree.print();
|
||||
printTree(this._tree);
|
||||
}
|
||||
|
||||
this._tree.assertInvariants();
|
||||
assertTreeInvariants(this._tree);
|
||||
|
||||
let actual = this._tree.getAllInOrder().map(n => new Interval(n.cachedAbsoluteStart, n.cachedAbsoluteEnd));
|
||||
let expected = this._oracle.intervals;
|
||||
@@ -553,3 +553,89 @@ suite('IntervalTree', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function printTree(T: IntervalTree): void {
|
||||
if (T.root === SENTINEL) {
|
||||
console.log(`~~ empty`);
|
||||
return;
|
||||
}
|
||||
let out: string[] = [];
|
||||
_printTree(T, T.root, '', 0, out);
|
||||
console.log(out.join(''));
|
||||
}
|
||||
|
||||
function _printTree(T: IntervalTree, n: IntervalNode, indent: string, delta: number, out: string[]): void {
|
||||
out.push(`${indent}[${getNodeColor(n) === NodeColor.Red ? 'R' : 'B'},${n.delta}, ${n.start}->${n.end}, ${n.maxEnd}] : {${delta + n.start}->${delta + n.end}}, maxEnd: ${n.maxEnd + delta}\n`);
|
||||
if (n.left !== SENTINEL) {
|
||||
_printTree(T, n.left, indent + ' ', delta, out);
|
||||
} else {
|
||||
out.push(`${indent} NIL\n`);
|
||||
}
|
||||
if (n.right !== SENTINEL) {
|
||||
_printTree(T, n.right, indent + ' ', delta + n.delta, out);
|
||||
} else {
|
||||
out.push(`${indent} NIL\n`);
|
||||
}
|
||||
}
|
||||
|
||||
//#region Assertion
|
||||
|
||||
function assertTreeInvariants(T: IntervalTree): void {
|
||||
assert(getNodeColor(SENTINEL) === NodeColor.Black);
|
||||
assert(SENTINEL.parent === SENTINEL);
|
||||
assert(SENTINEL.left === SENTINEL);
|
||||
assert(SENTINEL.right === SENTINEL);
|
||||
assert(SENTINEL.start === 0);
|
||||
assert(SENTINEL.end === 0);
|
||||
assert(SENTINEL.delta === 0);
|
||||
assert(T.root.parent === SENTINEL);
|
||||
assertValidTree(T);
|
||||
}
|
||||
|
||||
function depth(n: IntervalNode): number {
|
||||
if (n === SENTINEL) {
|
||||
// The leafs are black
|
||||
return 1;
|
||||
}
|
||||
assert(depth(n.left) === depth(n.right));
|
||||
return (getNodeColor(n) === NodeColor.Black ? 1 : 0) + depth(n.left);
|
||||
}
|
||||
|
||||
function assertValidNode(n: IntervalNode, delta): void {
|
||||
if (n === SENTINEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
let l = n.left;
|
||||
let r = n.right;
|
||||
|
||||
if (getNodeColor(n) === NodeColor.Red) {
|
||||
assert(getNodeColor(l) === NodeColor.Black);
|
||||
assert(getNodeColor(r) === NodeColor.Black);
|
||||
}
|
||||
|
||||
let expectedMaxEnd = n.end;
|
||||
if (l !== SENTINEL) {
|
||||
assert(intervalCompare(l.start + delta, l.end + delta, n.start + delta, n.end + delta) <= 0);
|
||||
expectedMaxEnd = Math.max(expectedMaxEnd, l.maxEnd);
|
||||
}
|
||||
if (r !== SENTINEL) {
|
||||
assert(intervalCompare(n.start + delta, n.end + delta, r.start + delta + n.delta, r.end + delta + n.delta) <= 0);
|
||||
expectedMaxEnd = Math.max(expectedMaxEnd, r.maxEnd + n.delta);
|
||||
}
|
||||
assert(n.maxEnd === expectedMaxEnd);
|
||||
|
||||
assertValidNode(l, delta);
|
||||
assertValidNode(r, delta + n.delta);
|
||||
}
|
||||
|
||||
function assertValidTree(T: IntervalTree): void {
|
||||
if (T.root === SENTINEL) {
|
||||
return;
|
||||
}
|
||||
assert(getNodeColor(T.root) === NodeColor.Black);
|
||||
assert(depth(T.root.left) === depth(T.root.right));
|
||||
assertValidNode(T.root, 0);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -11,7 +11,7 @@ import { MetadataConsts } from 'vs/editor/common/modes';
|
||||
import { ViewLineToken, ViewLineTokenFactory } from 'vs/editor/common/core/viewLineToken';
|
||||
|
||||
function assertLineTokens(_actual: LineTokens, _expected: TestToken[]): void {
|
||||
let expected = ViewLineTokenFactory.inflateArr(TestToken.toTokens(_expected), _actual.getLineLength());
|
||||
let expected = ViewLineTokenFactory.inflateArr(TestToken.toTokens(_expected), _actual.getLineContent().length);
|
||||
let actual = _actual.inflate();
|
||||
let decode = (token: ViewLineToken) => {
|
||||
return {
|
||||
@@ -1521,4 +1521,3 @@ suite('Editor Model - modelLine.append', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1154,7 +1154,6 @@ suite('deltaDecorations', () => {
|
||||
|
||||
assert.equal(initialIds.length, decorations.length, 'returns expected cnt of ids');
|
||||
assert.equal(initialIds.length, model.getAllDecorations().length, 'does not leak decorations');
|
||||
assert.equal(initialIds.length, model._getTrackedRangesCount(), 'does not leak tracked ranges');
|
||||
actualDecorations.sort((a, b) => strcmp(a.id, b.id));
|
||||
decorations.sort((a, b) => strcmp(a.id, b.id));
|
||||
assert.deepEqual(actualDecorations, decorations);
|
||||
@@ -1164,7 +1163,6 @@ suite('deltaDecorations', () => {
|
||||
|
||||
assert.equal(newIds.length, newDecorations.length, 'returns expected cnt of ids');
|
||||
assert.equal(newIds.length, model.getAllDecorations().length, 'does not leak decorations');
|
||||
assert.equal(newIds.length, model._getTrackedRangesCount(), 'does not leak tracked ranges');
|
||||
actualNewDecorations.sort((a, b) => strcmp(a.id, b.id));
|
||||
newDecorations.sort((a, b) => strcmp(a.id, b.id));
|
||||
assert.deepEqual(actualDecorations, decorations);
|
||||
|
||||
@@ -197,7 +197,7 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
|
||||
|
||||
class Mode extends MockMode {
|
||||
|
||||
private static _id = new LanguageIdentifier('textToHtmlTokenizerMode', 3);
|
||||
private static readonly _id = new LanguageIdentifier('textToHtmlTokenizerMode', 3);
|
||||
|
||||
constructor() {
|
||||
super(Mode._id);
|
||||
|
||||
@@ -7,19 +7,15 @@
|
||||
import * as assert from 'assert';
|
||||
import { DecorationSegment, LineDecorationsNormalizer, LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { InlineDecoration } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { InlineDecoration, InlineDecorationType } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
suite('Editor ViewLayout - ViewLineParts', () => {
|
||||
|
||||
function newDecoration(startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number, inlineClassName: string): InlineDecoration {
|
||||
return new InlineDecoration(new Range(startLineNumber, startColumn, endLineNumber, endColumn), inlineClassName, false);
|
||||
}
|
||||
|
||||
test('Bug 9827:Overlapping inline decorations can cause wrong inline class to be applied', () => {
|
||||
|
||||
var result = LineDecorationsNormalizer.normalize('abcabcabcabcabcabcabcabcabcabc', [
|
||||
new LineDecoration(1, 11, 'c1', false),
|
||||
new LineDecoration(3, 4, 'c2', false)
|
||||
new LineDecoration(1, 11, 'c1', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 4, 'c2', InlineDecorationType.Regular)
|
||||
]);
|
||||
|
||||
assert.deepEqual(result, [
|
||||
@@ -32,8 +28,8 @@ suite('Editor ViewLayout - ViewLineParts', () => {
|
||||
test('issue #3462: no whitespace shown at the end of a decorated line', () => {
|
||||
|
||||
var result = LineDecorationsNormalizer.normalize('abcabcabcabcabcabcabcabcabcabc', [
|
||||
new LineDecoration(15, 21, 'vs-whitespace', false),
|
||||
new LineDecoration(20, 21, 'inline-folded', false),
|
||||
new LineDecoration(15, 21, 'vs-whitespace', InlineDecorationType.Regular),
|
||||
new LineDecoration(20, 21, 'inline-folded', InlineDecorationType.Regular),
|
||||
]);
|
||||
|
||||
assert.deepEqual(result, [
|
||||
@@ -45,76 +41,88 @@ suite('Editor ViewLayout - ViewLineParts', () => {
|
||||
test('issue #3661: Link decoration bleeds to next line when wrapping', () => {
|
||||
|
||||
let result = LineDecoration.filter([
|
||||
newDecoration(2, 12, 3, 30, 'detected-link')
|
||||
new InlineDecoration(new Range(2, 12, 3, 30), 'detected-link', InlineDecorationType.Regular)
|
||||
], 3, 12, 500);
|
||||
|
||||
assert.deepEqual(result, [
|
||||
new LineDecoration(12, 30, 'detected-link', false),
|
||||
new LineDecoration(12, 30, 'detected-link', InlineDecorationType.Regular),
|
||||
]);
|
||||
});
|
||||
|
||||
test('issue #37401: Allow both before and after decorations on empty line', () => {
|
||||
let result = LineDecoration.filter([
|
||||
new InlineDecoration(new Range(4, 1, 4, 2), 'before', InlineDecorationType.Before),
|
||||
new InlineDecoration(new Range(4, 0, 4, 1), 'after', InlineDecorationType.After),
|
||||
], 4, 1, 500);
|
||||
|
||||
assert.deepEqual(result, [
|
||||
new LineDecoration(1, 2, 'before', InlineDecorationType.Before),
|
||||
new LineDecoration(0, 1, 'after', InlineDecorationType.After),
|
||||
]);
|
||||
});
|
||||
|
||||
test('ViewLineParts', () => {
|
||||
|
||||
assert.deepEqual(LineDecorationsNormalizer.normalize('abcabcabcabcabcabcabcabcabcabc', [
|
||||
new LineDecoration(1, 2, 'c1', false),
|
||||
new LineDecoration(3, 4, 'c2', false)
|
||||
new LineDecoration(1, 2, 'c1', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 4, 'c2', InlineDecorationType.Regular)
|
||||
]), [
|
||||
new DecorationSegment(0, 0, 'c1'),
|
||||
new DecorationSegment(2, 2, 'c2')
|
||||
]);
|
||||
|
||||
assert.deepEqual(LineDecorationsNormalizer.normalize('abcabcabcabcabcabcabcabcabcabc', [
|
||||
new LineDecoration(1, 3, 'c1', false),
|
||||
new LineDecoration(3, 4, 'c2', false)
|
||||
new LineDecoration(1, 3, 'c1', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 4, 'c2', InlineDecorationType.Regular)
|
||||
]), [
|
||||
new DecorationSegment(0, 1, 'c1'),
|
||||
new DecorationSegment(2, 2, 'c2')
|
||||
]);
|
||||
|
||||
assert.deepEqual(LineDecorationsNormalizer.normalize('abcabcabcabcabcabcabcabcabcabc', [
|
||||
new LineDecoration(1, 4, 'c1', false),
|
||||
new LineDecoration(3, 4, 'c2', false)
|
||||
new LineDecoration(1, 4, 'c1', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 4, 'c2', InlineDecorationType.Regular)
|
||||
]), [
|
||||
new DecorationSegment(0, 1, 'c1'),
|
||||
new DecorationSegment(2, 2, 'c1 c2')
|
||||
]);
|
||||
|
||||
assert.deepEqual(LineDecorationsNormalizer.normalize('abcabcabcabcabcabcabcabcabcabc', [
|
||||
new LineDecoration(1, 4, 'c1', false),
|
||||
new LineDecoration(1, 4, 'c1*', false),
|
||||
new LineDecoration(3, 4, 'c2', false)
|
||||
new LineDecoration(1, 4, 'c1', InlineDecorationType.Regular),
|
||||
new LineDecoration(1, 4, 'c1*', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 4, 'c2', InlineDecorationType.Regular)
|
||||
]), [
|
||||
new DecorationSegment(0, 1, 'c1 c1*'),
|
||||
new DecorationSegment(2, 2, 'c1 c1* c2')
|
||||
]);
|
||||
|
||||
assert.deepEqual(LineDecorationsNormalizer.normalize('abcabcabcabcabcabcabcabcabcabc', [
|
||||
new LineDecoration(1, 4, 'c1', false),
|
||||
new LineDecoration(1, 4, 'c1*', false),
|
||||
new LineDecoration(1, 4, 'c1**', false),
|
||||
new LineDecoration(3, 4, 'c2', false)
|
||||
new LineDecoration(1, 4, 'c1', InlineDecorationType.Regular),
|
||||
new LineDecoration(1, 4, 'c1*', InlineDecorationType.Regular),
|
||||
new LineDecoration(1, 4, 'c1**', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 4, 'c2', InlineDecorationType.Regular)
|
||||
]), [
|
||||
new DecorationSegment(0, 1, 'c1 c1* c1**'),
|
||||
new DecorationSegment(2, 2, 'c1 c1* c1** c2')
|
||||
]);
|
||||
|
||||
assert.deepEqual(LineDecorationsNormalizer.normalize('abcabcabcabcabcabcabcabcabcabc', [
|
||||
new LineDecoration(1, 4, 'c1', false),
|
||||
new LineDecoration(1, 4, 'c1*', false),
|
||||
new LineDecoration(1, 4, 'c1**', false),
|
||||
new LineDecoration(3, 4, 'c2', false),
|
||||
new LineDecoration(3, 4, 'c2*', false)
|
||||
new LineDecoration(1, 4, 'c1', InlineDecorationType.Regular),
|
||||
new LineDecoration(1, 4, 'c1*', InlineDecorationType.Regular),
|
||||
new LineDecoration(1, 4, 'c1**', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 4, 'c2', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 4, 'c2*', InlineDecorationType.Regular)
|
||||
]), [
|
||||
new DecorationSegment(0, 1, 'c1 c1* c1**'),
|
||||
new DecorationSegment(2, 2, 'c1 c1* c1** c2 c2*')
|
||||
]);
|
||||
|
||||
assert.deepEqual(LineDecorationsNormalizer.normalize('abcabcabcabcabcabcabcabcabcabc', [
|
||||
new LineDecoration(1, 4, 'c1', false),
|
||||
new LineDecoration(1, 4, 'c1*', false),
|
||||
new LineDecoration(1, 4, 'c1**', false),
|
||||
new LineDecoration(3, 4, 'c2', false),
|
||||
new LineDecoration(3, 5, 'c2*', false)
|
||||
new LineDecoration(1, 4, 'c1', InlineDecorationType.Regular),
|
||||
new LineDecoration(1, 4, 'c1*', InlineDecorationType.Regular),
|
||||
new LineDecoration(1, 4, 'c1**', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 4, 'c2', InlineDecorationType.Regular),
|
||||
new LineDecoration(3, 5, 'c2*', InlineDecorationType.Regular)
|
||||
]), [
|
||||
new DecorationSegment(0, 1, 'c1 c1* c1**'),
|
||||
new DecorationSegment(2, 2, 'c1 c1* c1** c2 c2*'),
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { MetadataConsts } from 'vs/editor/common/modes';
|
||||
import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations';
|
||||
import { InlineDecorationType } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
suite('viewLineRenderer.renderLine', () => {
|
||||
|
||||
@@ -700,7 +701,7 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
false,
|
||||
0,
|
||||
[createPart(21, 3)],
|
||||
[new LineDecoration(1, 22, 'link', false)],
|
||||
[new LineDecoration(1, 22, 'link', InlineDecorationType.Regular)],
|
||||
4,
|
||||
10,
|
||||
-1,
|
||||
@@ -735,7 +736,7 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
createPart(84, 6),
|
||||
],
|
||||
[
|
||||
new LineDecoration(13, 51, 'detected-link', false)
|
||||
new LineDecoration(13, 51, 'detected-link', InlineDecorationType.Regular)
|
||||
],
|
||||
4,
|
||||
10,
|
||||
@@ -993,9 +994,9 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
0,
|
||||
[createPart(11, 0)],
|
||||
[
|
||||
new LineDecoration(5, 7, 'a', false),
|
||||
new LineDecoration(1, 3, 'b', false),
|
||||
new LineDecoration(2, 8, 'c', false),
|
||||
new LineDecoration(5, 7, 'a', InlineDecorationType.Regular),
|
||||
new LineDecoration(1, 3, 'b', InlineDecorationType.Regular),
|
||||
new LineDecoration(2, 8, 'c', InlineDecorationType.Regular),
|
||||
],
|
||||
4,
|
||||
10,
|
||||
@@ -1033,7 +1034,7 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
false,
|
||||
0,
|
||||
[createPart(4, 3)],
|
||||
[new LineDecoration(1, 2, 'before', true)],
|
||||
[new LineDecoration(1, 2, 'before', InlineDecorationType.Before)],
|
||||
4,
|
||||
10,
|
||||
-1,
|
||||
@@ -1062,7 +1063,7 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
false,
|
||||
0,
|
||||
[createPart(4, 3)],
|
||||
[new LineDecoration(2, 3, 'before', true)],
|
||||
[new LineDecoration(2, 3, 'before', InlineDecorationType.Before)],
|
||||
4,
|
||||
10,
|
||||
-1,
|
||||
@@ -1092,7 +1093,7 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
false,
|
||||
0,
|
||||
[createPart(0, 3)],
|
||||
[new LineDecoration(1, 2, 'before', true)],
|
||||
[new LineDecoration(1, 2, 'before', InlineDecorationType.Before)],
|
||||
4,
|
||||
10,
|
||||
-1,
|
||||
@@ -1103,7 +1104,7 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
|
||||
let expected = [
|
||||
'<span>',
|
||||
'<span class="before">\u00a0</span>',
|
||||
'<span class="before"></span>',
|
||||
'</span>'
|
||||
].join('');
|
||||
|
||||
@@ -1118,7 +1119,7 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
false,
|
||||
0,
|
||||
[createPart(7, 3)],
|
||||
[new LineDecoration(7, 8, 'inline-folded', true)],
|
||||
[new LineDecoration(7, 8, 'inline-folded', InlineDecorationType.After)],
|
||||
2,
|
||||
10,
|
||||
10000,
|
||||
@@ -1137,6 +1138,65 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
assert.deepEqual(actual.html, expected);
|
||||
});
|
||||
|
||||
test('issue #37401: Allow both before and after decorations on empty line', () => {
|
||||
|
||||
let actual = renderViewLine(new RenderLineInput(
|
||||
true,
|
||||
'',
|
||||
false,
|
||||
0,
|
||||
[createPart(0, 3)],
|
||||
[
|
||||
new LineDecoration(1, 2, 'before', InlineDecorationType.Before),
|
||||
new LineDecoration(0, 1, 'after', InlineDecorationType.After),
|
||||
],
|
||||
2,
|
||||
10,
|
||||
10000,
|
||||
'none',
|
||||
false,
|
||||
false
|
||||
));
|
||||
|
||||
let expected = [
|
||||
'<span>',
|
||||
'<span class="before after"></span>',
|
||||
'</span>'
|
||||
].join('');
|
||||
|
||||
assert.deepEqual(actual.html, expected);
|
||||
});
|
||||
|
||||
test('issue #38935: GitLens end-of-line blame no longer rendering', () => {
|
||||
|
||||
let actual = renderViewLine(new RenderLineInput(
|
||||
true,
|
||||
'\t}',
|
||||
false,
|
||||
0,
|
||||
[createPart(2, 3)],
|
||||
[
|
||||
new LineDecoration(3, 3, 'ced-TextEditorDecorationType2-5e9b9b3f-3 ced-TextEditorDecorationType2-3', InlineDecorationType.Before),
|
||||
new LineDecoration(3, 3, 'ced-TextEditorDecorationType2-5e9b9b3f-4 ced-TextEditorDecorationType2-4', InlineDecorationType.After),
|
||||
],
|
||||
4,
|
||||
10,
|
||||
10000,
|
||||
'none',
|
||||
false,
|
||||
false
|
||||
));
|
||||
|
||||
let expected = [
|
||||
'<span>',
|
||||
'<span class="mtk3">\u00a0\u00a0\u00a0\u00a0}</span>',
|
||||
'<span class="ced-TextEditorDecorationType2-5e9b9b3f-3 ced-TextEditorDecorationType2-3 ced-TextEditorDecorationType2-5e9b9b3f-4 ced-TextEditorDecorationType2-4"></span>',
|
||||
'</span>'
|
||||
].join('');
|
||||
|
||||
assert.deepEqual(actual.html, expected);
|
||||
});
|
||||
|
||||
function createTestGetColumnOfLinePartOffset(lineContent: string, tabSize: number, parts: ViewLineToken[], expectedPartLengths: number[]): (partIndex: number, partLength: number, offset: number, expected: number) => void {
|
||||
let renderLineOutput = renderViewLine(new RenderLineInput(
|
||||
false,
|
||||
|
||||
@@ -32,22 +32,22 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
|
||||
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++) {
|
||||
for (let col = 1; col <= 14; col++) {
|
||||
assert.equal(line1.getModelColumnOfViewPosition(0, col), col, 'getInputColumnOfOutputPosition(0, ' + col + ')');
|
||||
}
|
||||
for (var col = 1; col <= 15; col++) {
|
||||
for (let col = 1; col <= 15; col++) {
|
||||
assert.equal(line1.getModelColumnOfViewPosition(1, col), 13 + col, 'getInputColumnOfOutputPosition(1, ' + col + ')');
|
||||
}
|
||||
for (var col = 1; col <= 16; col++) {
|
||||
for (let col = 1; col <= 16; col++) {
|
||||
assert.equal(line1.getModelColumnOfViewPosition(2, col), 13 + 14 + col, 'getInputColumnOfOutputPosition(2, ' + col + ')');
|
||||
}
|
||||
for (var col = 1; col <= 13; col++) {
|
||||
for (let col = 1; col <= 13; col++) {
|
||||
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(0, col), 'getOutputPositionOfInputPosition(' + col + ')');
|
||||
}
|
||||
for (var col = 1 + 13; col <= 14 + 13; col++) {
|
||||
for (let col = 1 + 13; col <= 14 + 13; col++) {
|
||||
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(1, col - 13), 'getOutputPositionOfInputPosition(' + col + ')');
|
||||
}
|
||||
for (var col = 1 + 13 + 14; col <= 15 + 14 + 13; col++) {
|
||||
for (let col = 1 + 13 + 14; col <= 15 + 14 + 13; col++) {
|
||||
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(2, col - 13 - 14), 'getOutputPositionOfInputPosition(' + col + ')');
|
||||
}
|
||||
|
||||
@@ -61,28 +61,28 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
|
||||
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++) {
|
||||
for (let col = 1; col <= 14; col++) {
|
||||
assert.equal(line1.getModelColumnOfViewPosition(0, col), col, 'getInputColumnOfOutputPosition(0, ' + col + ')');
|
||||
}
|
||||
for (var col = 1; col <= 1; col++) {
|
||||
for (let col = 1; col <= 1; col++) {
|
||||
assert.equal(line1.getModelColumnOfViewPosition(1, 1), 13 + col, 'getInputColumnOfOutputPosition(1, ' + col + ')');
|
||||
}
|
||||
for (var col = 2; col <= 16; col++) {
|
||||
for (let col = 2; col <= 16; col++) {
|
||||
assert.equal(line1.getModelColumnOfViewPosition(1, col), 13 + col - 1, 'getInputColumnOfOutputPosition(1, ' + col + ')');
|
||||
}
|
||||
for (var col = 1; col <= 1; col++) {
|
||||
for (let col = 1; col <= 1; col++) {
|
||||
assert.equal(line1.getModelColumnOfViewPosition(2, col), 13 + 14 + col, 'getInputColumnOfOutputPosition(2, ' + col + ')');
|
||||
}
|
||||
for (var col = 2; col <= 17; col++) {
|
||||
for (let col = 2; col <= 17; col++) {
|
||||
assert.equal(line1.getModelColumnOfViewPosition(2, col), 13 + 14 + col - 1, 'getInputColumnOfOutputPosition(2, ' + col + ')');
|
||||
}
|
||||
for (var col = 1; col <= 13; col++) {
|
||||
for (let col = 1; col <= 13; col++) {
|
||||
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(0, col), 'getOutputPositionOfInputPosition(' + col + ')');
|
||||
}
|
||||
for (var col = 1 + 13; col <= 14 + 13; col++) {
|
||||
for (let col = 1 + 13; col <= 14 + 13; 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++) {
|
||||
for (let col = 1 + 13 + 14; col <= 15 + 14 + 13; col++) {
|
||||
assert.deepEqual(line1.getViewPositionOfModelPosition(0, col), pos(2, 1 + col - 13 - 14), 'getOutputPositionOfInputPosition(' + col + ')');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
import { Model } from 'vs/editor/common/model/model';
|
||||
import { TestConfiguration } from 'vs/editor/test/common/mocks/testConfiguration';
|
||||
import { ViewModel } from 'vs/editor/common/viewModel/viewModelImpl';
|
||||
import { MockCodeEditorCreationOptions } from 'vs/editor/test/common/mocks/mockCodeEditor';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
export function testViewModel(text: string[], options: MockCodeEditorCreationOptions, callback: (viewModel: ViewModel, model: Model) => void): void {
|
||||
export function testViewModel(text: string[], options: IEditorOptions, callback: (viewModel: ViewModel, model: Model) => void): void {
|
||||
const EDITOR_ID = 1;
|
||||
|
||||
let configuration = new TestConfiguration(options);
|
||||
|
||||
@@ -7,14 +7,15 @@
|
||||
import * as assert from 'assert';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { testViewModel } from 'vs/editor/test/common/viewModel/testViewModel';
|
||||
import { MockCodeEditorCreationOptions } from 'vs/editor/test/common/mocks/mockCodeEditor';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { InlineDecorationType } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
suite('ViewModelDecorations', () => {
|
||||
test('getDecorationsViewportData', () => {
|
||||
const text = [
|
||||
'hello world, this is a buffer that will be wrapped'
|
||||
];
|
||||
const opts: MockCodeEditorCreationOptions = {
|
||||
const opts: IEditorOptions = {
|
||||
wordWrap: 'wordWrapColumn',
|
||||
wordWrapColumn: 13
|
||||
};
|
||||
@@ -25,21 +26,6 @@ suite('ViewModelDecorations', () => {
|
||||
assert.equal(viewModel.getLineContent(4), 'will be ');
|
||||
assert.equal(viewModel.getLineContent(5), 'wrapped');
|
||||
|
||||
let dec1: string;
|
||||
let dec2: string;
|
||||
let dec3: string;
|
||||
let dec4: string;
|
||||
let dec5: string;
|
||||
let dec6: string;
|
||||
let dec7: string;
|
||||
let dec8: string;
|
||||
let dec9: string;
|
||||
let dec10: string;
|
||||
let dec11: string;
|
||||
let dec12: string;
|
||||
let dec13: string;
|
||||
let dec14: string;
|
||||
let dec15: string;
|
||||
model.changeDecorations((accessor) => {
|
||||
let createOpts = (id: string) => {
|
||||
return {
|
||||
@@ -53,39 +39,39 @@ suite('ViewModelDecorations', () => {
|
||||
// VIEWPORT will be (1,14) -> (1,36)
|
||||
|
||||
// completely before viewport
|
||||
dec1 = accessor.addDecoration(new Range(1, 2, 1, 3), createOpts('dec1'));
|
||||
accessor.addDecoration(new Range(1, 2, 1, 3), createOpts('dec1'));
|
||||
// starts before viewport, ends at viewport start
|
||||
dec2 = accessor.addDecoration(new Range(1, 2, 1, 14), createOpts('dec2'));
|
||||
accessor.addDecoration(new Range(1, 2, 1, 14), createOpts('dec2'));
|
||||
// starts before viewport, ends inside viewport
|
||||
dec3 = accessor.addDecoration(new Range(1, 2, 1, 15), createOpts('dec3'));
|
||||
accessor.addDecoration(new Range(1, 2, 1, 15), createOpts('dec3'));
|
||||
// starts before viewport, ends at viewport end
|
||||
dec4 = accessor.addDecoration(new Range(1, 2, 1, 36), createOpts('dec4'));
|
||||
accessor.addDecoration(new Range(1, 2, 1, 36), createOpts('dec4'));
|
||||
// starts before viewport, ends after viewport
|
||||
dec5 = accessor.addDecoration(new Range(1, 2, 1, 51), createOpts('dec5'));
|
||||
accessor.addDecoration(new Range(1, 2, 1, 51), createOpts('dec5'));
|
||||
|
||||
// starts at viewport start, ends at viewport start
|
||||
dec6 = accessor.addDecoration(new Range(1, 14, 1, 14), createOpts('dec6'));
|
||||
accessor.addDecoration(new Range(1, 14, 1, 14), createOpts('dec6'));
|
||||
// starts at viewport start, ends inside viewport
|
||||
dec7 = accessor.addDecoration(new Range(1, 14, 1, 16), createOpts('dec7'));
|
||||
accessor.addDecoration(new Range(1, 14, 1, 16), createOpts('dec7'));
|
||||
// starts at viewport start, ends at viewport end
|
||||
dec8 = accessor.addDecoration(new Range(1, 14, 1, 36), createOpts('dec8'));
|
||||
accessor.addDecoration(new Range(1, 14, 1, 36), createOpts('dec8'));
|
||||
// starts at viewport start, ends after viewport
|
||||
dec9 = accessor.addDecoration(new Range(1, 14, 1, 51), createOpts('dec9'));
|
||||
accessor.addDecoration(new Range(1, 14, 1, 51), createOpts('dec9'));
|
||||
|
||||
// starts inside viewport, ends inside viewport
|
||||
dec10 = accessor.addDecoration(new Range(1, 16, 1, 18), createOpts('dec10'));
|
||||
accessor.addDecoration(new Range(1, 16, 1, 18), createOpts('dec10'));
|
||||
// starts inside viewport, ends at viewport end
|
||||
dec11 = accessor.addDecoration(new Range(1, 16, 1, 36), createOpts('dec11'));
|
||||
accessor.addDecoration(new Range(1, 16, 1, 36), createOpts('dec11'));
|
||||
// starts inside viewport, ends after viewport
|
||||
dec12 = accessor.addDecoration(new Range(1, 16, 1, 51), createOpts('dec12'));
|
||||
accessor.addDecoration(new Range(1, 16, 1, 51), createOpts('dec12'));
|
||||
|
||||
// starts at viewport end, ends at viewport end
|
||||
dec13 = accessor.addDecoration(new Range(1, 36, 1, 36), createOpts('dec13'));
|
||||
accessor.addDecoration(new Range(1, 36, 1, 36), createOpts('dec13'));
|
||||
// starts at viewport end, ends after viewport
|
||||
dec14 = accessor.addDecoration(new Range(1, 36, 1, 51), createOpts('dec14'));
|
||||
accessor.addDecoration(new Range(1, 36, 1, 51), createOpts('dec14'));
|
||||
|
||||
// starts after viewport, ends after viewport
|
||||
dec15 = accessor.addDecoration(new Range(1, 40, 1, 51), createOpts('dec15'));
|
||||
accessor.addDecoration(new Range(1, 40, 1, 51), createOpts('dec15'));
|
||||
});
|
||||
|
||||
let actualDecorations = viewModel.getDecorationsInViewport(
|
||||
@@ -120,107 +106,117 @@ suite('ViewModelDecorations', () => {
|
||||
{
|
||||
range: new Range(1, 2, 2, 1),
|
||||
inlineClassName: 'i-dec2',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 2, 1),
|
||||
inlineClassName: 'a-dec2',
|
||||
type: InlineDecorationType.After
|
||||
},
|
||||
{
|
||||
range: new Range(1, 2, 2, 2),
|
||||
inlineClassName: 'i-dec3',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 2, 2),
|
||||
range: new Range(2, 2, 2, 2),
|
||||
inlineClassName: 'a-dec3',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.After
|
||||
},
|
||||
{
|
||||
range: new Range(1, 2, 4, 1),
|
||||
inlineClassName: 'i-dec4',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(1, 2, 5, 8),
|
||||
inlineClassName: 'i-dec5',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 2, 1),
|
||||
inlineClassName: 'i-dec6',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 2, 2),
|
||||
range: new Range(2, 1, 2, 1),
|
||||
inlineClassName: 'b-dec6',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.Before
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 2, 1),
|
||||
inlineClassName: 'a-dec6',
|
||||
type: InlineDecorationType.After
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 2, 3),
|
||||
inlineClassName: 'i-dec7',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 2, 2),
|
||||
range: new Range(2, 1, 2, 1),
|
||||
inlineClassName: 'b-dec7',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.Before
|
||||
},
|
||||
{
|
||||
range: new Range(2, 2, 2, 3),
|
||||
range: new Range(2, 3, 2, 3),
|
||||
inlineClassName: 'a-dec7',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.After
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 4, 1),
|
||||
inlineClassName: 'i-dec8',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 2, 2),
|
||||
range: new Range(2, 1, 2, 1),
|
||||
inlineClassName: 'b-dec8',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.Before
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 5, 8),
|
||||
inlineClassName: 'i-dec9',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 2, 2),
|
||||
range: new Range(2, 1, 2, 1),
|
||||
inlineClassName: 'b-dec9',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.Before
|
||||
},
|
||||
{
|
||||
range: new Range(2, 3, 2, 5),
|
||||
inlineClassName: 'i-dec10',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 3, 2, 4),
|
||||
range: new Range(2, 3, 2, 3),
|
||||
inlineClassName: 'b-dec10',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.Before
|
||||
},
|
||||
{
|
||||
range: new Range(2, 4, 2, 5),
|
||||
range: new Range(2, 5, 2, 5),
|
||||
inlineClassName: 'a-dec10',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.After
|
||||
},
|
||||
{
|
||||
range: new Range(2, 3, 4, 1),
|
||||
inlineClassName: 'i-dec11',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 3, 2, 4),
|
||||
range: new Range(2, 3, 2, 3),
|
||||
inlineClassName: 'b-dec11',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.Before
|
||||
},
|
||||
{
|
||||
range: new Range(2, 3, 5, 8),
|
||||
inlineClassName: 'i-dec12',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 3, 2, 4),
|
||||
range: new Range(2, 3, 2, 3),
|
||||
inlineClassName: 'b-dec12',
|
||||
insertsBeforeOrAfter: true
|
||||
type: InlineDecorationType.Before
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -234,32 +230,32 @@ suite('ViewModelDecorations', () => {
|
||||
{
|
||||
range: new Range(1, 2, 4, 1),
|
||||
inlineClassName: 'i-dec4',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(1, 2, 5, 8),
|
||||
inlineClassName: 'i-dec5',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 4, 1),
|
||||
inlineClassName: 'i-dec8',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 1, 5, 8),
|
||||
inlineClassName: 'i-dec9',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 3, 4, 1),
|
||||
inlineClassName: 'i-dec11',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
{
|
||||
range: new Range(2, 3, 5, 8),
|
||||
inlineClassName: 'i-dec12',
|
||||
insertsBeforeOrAfter: false
|
||||
type: InlineDecorationType.Regular
|
||||
},
|
||||
]);
|
||||
});
|
||||
@@ -269,7 +265,7 @@ suite('ViewModelDecorations', () => {
|
||||
const text = [
|
||||
'hello world, this is a buffer that will be wrapped'
|
||||
];
|
||||
const opts: MockCodeEditorCreationOptions = {
|
||||
const opts: IEditorOptions = {
|
||||
wordWrap: 'wordWrapColumn',
|
||||
wordWrapColumn: 13
|
||||
};
|
||||
@@ -280,9 +276,8 @@ suite('ViewModelDecorations', () => {
|
||||
assert.equal(viewModel.getLineContent(4), 'will be ');
|
||||
assert.equal(viewModel.getLineContent(5), 'wrapped');
|
||||
|
||||
let dec1: string;
|
||||
model.changeDecorations((accessor) => {
|
||||
dec1 = accessor.addDecoration(
|
||||
accessor.addDecoration(
|
||||
new Range(1, 50, 1, 51),
|
||||
{
|
||||
beforeContentClassName: 'dec1'
|
||||
@@ -308,4 +303,39 @@ suite('ViewModelDecorations', () => {
|
||||
assert.deepEqual(inlineDecorations2, []);
|
||||
});
|
||||
});
|
||||
|
||||
test('issue #37401: Allow both before and after decorations on empty line', () => {
|
||||
const text = [
|
||||
''
|
||||
];
|
||||
testViewModel(text, {}, (viewModel, model) => {
|
||||
|
||||
model.changeDecorations((accessor) => {
|
||||
accessor.addDecoration(
|
||||
new Range(1, 1, 1, 1),
|
||||
{
|
||||
beforeContentClassName: 'before1',
|
||||
afterContentClassName: 'after1'
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
let inlineDecorations = viewModel.getViewLineRenderingData(
|
||||
new Range(1, 1, 1, 1),
|
||||
1
|
||||
).inlineDecorations;
|
||||
assert.deepEqual(inlineDecorations, [
|
||||
{
|
||||
range: new Range(1, 1, 1, 1),
|
||||
inlineClassName: 'before1',
|
||||
type: InlineDecorationType.Before
|
||||
},
|
||||
{
|
||||
range: new Range(1, 1, 1, 1),
|
||||
inlineClassName: 'after1',
|
||||
type: InlineDecorationType.After
|
||||
}
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user