diff --git a/src/vs/editor/contrib/linesOperations/common/moveLinesCommand.ts b/src/vs/editor/contrib/linesOperations/common/moveLinesCommand.ts old mode 100644 new mode 100755 index 43ed98d212d82..0d88af2f51875 --- a/src/vs/editor/contrib/linesOperations/common/moveLinesCommand.ts +++ b/src/vs/editor/contrib/linesOperations/common/moveLinesCommand.ts @@ -7,6 +7,8 @@ import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { ICommand, ICursorStateComputerData, IEditOperationBuilder, ITokenizedModel } from 'vs/editor/common/editorCommon'; +import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; +import Strings = require('vs/base/common/strings'); export class MoveLinesCommand implements ICommand { @@ -21,6 +23,17 @@ export class MoveLinesCommand implements ICommand { this._isMovingDown = isMovingDown; } + public static getBeginWhitespaces(string: string) { + return string.match(/^\s*/)[0] || ''; + } + + public static replaceLine(model: ITokenizedModel, builder: IEditOperationBuilder, lineNumber: number, newText: string) { + builder.addEditOperation(new Range( + lineNumber, 1, + lineNumber, model.getLineMaxColumn(lineNumber) + ), newText); + } + public getEditOperations(model: ITokenizedModel, builder: IEditOperationBuilder): void { var modelLineCount = model.getLineCount(); @@ -64,10 +77,50 @@ export class MoveLinesCommand implements ICommand { var movingLineNumber: number, movingLineText: string; + const options = model.getOptions(); + let oneIndent = ' '; + if (options.insertSpaces) { + oneIndent = Array(options.tabSize).join(' '); + } + + let bracketsSupport = LanguageConfigurationRegistry.getBracketsSupport(model.getLanguageIdentifier().id); + const lineComment = Strings.escapeRegExpCharacters(LanguageConfigurationRegistry.getComments(model.getLanguageIdentifier().id).lineCommentToken); + let brackets = []; + // If language have brackets, use them to detect blocks + if (bracketsSupport) { + brackets = bracketsSupport.brackets; + } + if (this._isMovingDown) { movingLineNumber = s.endLineNumber + 1; movingLineText = model.getLineContent(movingLineNumber); + let movingLineWhitespaces = MoveLinesCommand.getBeginWhitespaces(model.getLineContent(movingLineNumber)); + const firstLineWhitespaces = MoveLinesCommand.getBeginWhitespaces(model.getLineContent(s.startLineNumber)); + const lastLineWhitespaces = MoveLinesCommand.getBeginWhitespaces(model.getLineContent(s.endLineNumber)); + + // If selection have the same indentation for the first and last line, apply an auto indent to the selected block + if (firstLineWhitespaces.length === lastLineWhitespaces.length && movingLineText.length > 0) { + for (var lineNumber = s.startLineNumber; lineNumber <= s.endLineNumber; ++lineNumber) { + // If line end with language open bracket, use indentation of the next next line + let newMovingWhitespaces = movingLineWhitespaces; + + const allOpenbrackets = Strings.escapeRegExpCharacters(brackets.map(x => x.open).reduce((x, y) => x + y, '')); + + if ( + movingLineText.match(new RegExp('[' + allOpenbrackets + ']\\s*(' + lineComment + '.*)?$')) && + !movingLineText.match(new RegExp(lineComment + '.*[' + allOpenbrackets + ']\\s*(' + lineComment + '.*)?$')) + ) { + newMovingWhitespaces += oneIndent; + } + // Replace the current line whitespaces with the moving line whitespaces + const lineText = model.getLineContent(lineNumber).replace( + new RegExp('^' + firstLineWhitespaces), newMovingWhitespaces + ); + MoveLinesCommand.replaceLine(model, builder, lineNumber, lineText); + } + } + // Delete line that needs to be moved builder.addEditOperation(new Range(movingLineNumber - 1, model.getLineMaxColumn(movingLineNumber - 1), movingLineNumber, model.getLineMaxColumn(movingLineNumber)), null); @@ -77,6 +130,28 @@ export class MoveLinesCommand implements ICommand { movingLineNumber = s.startLineNumber - 1; movingLineText = model.getLineContent(movingLineNumber); + let movingLineWhitespaces = MoveLinesCommand.getBeginWhitespaces(model.getLineContent(movingLineNumber)); + const firstLineWhitespaces = MoveLinesCommand.getBeginWhitespaces(model.getLineContent(s.startLineNumber)); + const lastLineWhitespaces = MoveLinesCommand.getBeginWhitespaces(model.getLineContent(s.endLineNumber)); + + // If selection have the same indentation for the first and last line, apply an auto indent to the selected block + if (firstLineWhitespaces.length === lastLineWhitespaces.length && movingLineText.length > 0) { + for (var lineNumber = s.startLineNumber; lineNumber <= s.endLineNumber; ++lineNumber) { + // If line start with language closing bracket, use indentation of the next next line + const allClosingbrackets = Strings.escapeRegExpCharacters(brackets.map(x => x.close).reduce((x, y) => x + y, '')); + let newMovingWhitespaces = movingLineWhitespaces; + + if (movingLineText.match(new RegExp('^\\s*[' + allClosingbrackets + ']'))) { + newMovingWhitespaces += oneIndent; + } + // Replace the current line whitespaces with the moving line whitespaces + const lineText = model.getLineContent(lineNumber).replace( + new RegExp('^' + firstLineWhitespaces), newMovingWhitespaces + ); + MoveLinesCommand.replaceLine(model, builder, lineNumber, lineText); + } + } + // Delete line that needs to be moved builder.addEditOperation(new Range(movingLineNumber, 1, movingLineNumber + 1, 1), null); @@ -98,3 +173,4 @@ export class MoveLinesCommand implements ICommand { return result; } } + diff --git a/src/vs/editor/contrib/linesOperations/test/common/moveLinesCommand.test.ts b/src/vs/editor/contrib/linesOperations/test/common/moveLinesCommand.test.ts old mode 100644 new mode 100755 index 429d896276ebb..11b77c8e1b737 --- a/src/vs/editor/contrib/linesOperations/test/common/moveLinesCommand.test.ts +++ b/src/vs/editor/contrib/linesOperations/test/common/moveLinesCommand.test.ts @@ -7,13 +7,82 @@ import { Selection } from 'vs/editor/common/core/selection'; import { MoveLinesCommand } from 'vs/editor/contrib/linesOperations/common/moveLinesCommand'; import { testCommand } from 'vs/editor/test/common/commands/commandTestUtils'; +import * as editorCommon from 'vs/editor/common/editorCommon'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { MockMode } from 'vs/editor/test/common/mocks/mockMode'; +import { LanguageIdentifier } from 'vs/editor/common/modes'; +import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; -function testMoveLinesDownCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void { - testCommand(lines, null, selection, (sel) => new MoveLinesCommand(sel, true), expectedLines, expectedSelection); +const openBlockChars = ['{', '(', '[']; +const closingBlockChars = ['}', ')', ']']; +const indentationType = [' ', ' ', ' ']; +const lineComment = '//'; + +class BracketMode extends MockMode { + private static _id = new LanguageIdentifier('bracketMode', 3); + + constructor() { + super(BracketMode._id); + this._register(LanguageConfigurationRegistry.register(this.getLanguageIdentifier(), { + brackets: [ + [openBlockChars[0], closingBlockChars[0]], + [openBlockChars[1], closingBlockChars[1]], + [openBlockChars[2], closingBlockChars[2]], + ], + comments: { + 'lineComment': lineComment + } + })); + } +} + +function testMoveLinesDownCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection, options: editorCommon.ITextModelCreationOptions = undefined): void { + const mode = new BracketMode(); + testCommand(lines, mode.getLanguageIdentifier(), selection, (sel) => new MoveLinesCommand(sel, true), expectedLines, expectedSelection, options); } -function testMoveLinesUpCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void { - testCommand(lines, null, selection, (sel) => new MoveLinesCommand(sel, false), expectedLines, expectedSelection); +function testMoveLinesUpCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection, options: editorCommon.ITextModelCreationOptions = undefined): void { + const mode = new BracketMode(); + testCommand(lines, mode.getLanguageIdentifier(), selection, (sel) => new MoveLinesCommand(sel, false), expectedLines, expectedSelection, options); +} + +function getOptionWithIndentation(indentation: string): editorCommon.ITextModelCreationOptions { + let options: editorCommon.ITextModelCreationOptions = TextModel.DEFAULT_CREATION_OPTIONS; + + options.tabSize = indentation.length + 1; + options.insertSpaces = true; + + if (indentation.match(/\t/)) { + options.insertSpaces = false; + } + + return options; +} + +function testMoveLinesUpCommandWithAndWithoutPreindentation(oneIndentation: string, lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection) { + const options = getOptionWithIndentation(oneIndentation); + + testMoveLinesUpCommand(lines, selection, expectedLines, expectedSelection, options); + testMoveLinesUpCommand( + lines.map((x: string) => { return oneIndentation + oneIndentation + x; }), + selection, + expectedLines.map((x: string) => { return oneIndentation + oneIndentation + x; }), + expectedSelection, + options + ); +} + +function testMoveLinesDownCommandWithAndWithoutPreindentation(oneIndentation: string, lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection) { + const options = getOptionWithIndentation(oneIndentation); + + testMoveLinesDownCommand(lines, selection, expectedLines, expectedSelection, options); + testMoveLinesDownCommand( + lines.map((x: string) => { return oneIndentation + oneIndentation + x; }), + selection, + expectedLines.map((x: string) => { return oneIndentation + oneIndentation + x; }), + expectedSelection, + options + ); } suite('Editor Contrib - Move Lines Command', () => { @@ -246,5 +315,667 @@ suite('Editor Contrib - Move Lines Command', () => { new Selection(3, 1, 2, 1) ); }); + + test('move line down enter block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'line to move', + 'start block ' + openBracket, + indentation + 'let a = 10', + 'end block', + ], + new Selection(1, 1, 1, 1), + [ + 'start block ' + openBracket, + indentation + 'line to move', + indentation + 'let a = 10', + 'end block', + ], + new Selection(2, 1, 2, 1) + ); + }); + }); + }); + + test('move line down leave block', function () { + closingBlockChars.forEach((closingBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block', + indentation + 'let a = 10', + indentation + 'line to move', + closingBracket + 'end block', + ], + new Selection(3, 1, 3, 1), + [ + 'open block', + indentation + 'let a = 10', + closingBracket + 'end block', + 'line to move', + ], + new Selection(4, 1, 4, 1) + ); + }); + }); + }); + + test('move line down enter empty block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'line to move', + 'start block ' + openBracket, + 'end block', + ], + new Selection(1, 1, 1, 1), + [ + 'start block ' + openBracket, + indentation + 'line to move', + 'end block', + ], + new Selection(2, 1, 2, 1) + ); + }); + }); + }); + + test('move line down leave empty block', function () { + closingBlockChars.forEach((closingBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block', + indentation + 'line to move', + closingBracket + 'end block', + ], + new Selection(2, 1, 2, 1), + [ + 'open block', + closingBracket + 'end block', + 'line to move', + ], + new Selection(3, 1, 3, 1) + ); + }); + }); + }); + + test('move line up enter block', function () { + closingBlockChars.forEach((closingBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block', + indentation + 'let a = 10', + closingBracket + 'end block', + 'line to move', + ], + new Selection(4, 1, 4, 1), + [ + 'open block', + indentation + 'let a = 10', + indentation + 'line to move', + closingBracket + 'end block', + ], + new Selection(3, 1, 3, 1) + ); + }); + }); + }); + + test('move line up leave block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block ' + openBracket, + indentation + 'line to move', + indentation + 'let a = 10', + 'end block', + ], + new Selection(2, 1, 2, 1), + [ + 'line to move', + 'open block ' + openBracket, + indentation + 'let a = 10', + 'end block', + ], + new Selection(1, 1, 1, 1) + ); + }); + }); + }); + + test('move line up enter empty block', function () { + closingBlockChars.forEach((closingBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block', + closingBracket + 'end block', + 'line to move', + ], + new Selection(3, 1, 3, 1), + [ + 'open block', + indentation + 'line to move', + closingBracket + 'end block', + ], + new Selection(2, 1, 2, 1) + ); + }); + }); + }); + + test('move line up leave empty block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block ' + openBracket, + indentation + 'line to move', + 'end block', + ], + new Selection(2, 1, 2, 1), + [ + 'line to move', + 'open block ' + openBracket, + 'end block', + ], + new Selection(1, 1, 1, 1) + ); + }); + }); + }); + + test('move lines up through empty line', function () { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommand( + [ + indentation + 'another line', + '', + indentation + 'line to move', + ], + new Selection(3, 1, 3, 1), + [ + indentation + 'another line', + indentation + 'line to move', + '', + ], + new Selection(2, 1, 2, 1) + ); + }); + }); + + test('move lines down through empty line', function () { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommand( + [ + indentation + 'another line', + indentation + 'line to move', + '', + ], + new Selection(2, 1, 2, 1), + [ + indentation + 'another line', + '', + indentation + 'line to move', + ], + new Selection(3, 1, 3, 1) + ); + }); + }); + + test('move lines down enter block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + 'open block' + openBracket, + indentation + 'let a = 10', + 'end block', + ], + new Selection(1, 1, 3, 2), + [ + 'open block' + openBracket, + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + indentation + 'let a = 10', + 'end block', + ], + new Selection(2, 1, 4, 2) + ); + }); + }); + }); + + test('move lines down leave block', function () { + closingBlockChars.forEach((closingBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block', + indentation + 'let a = 10', + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + closingBracket + 'end block', + ], + new Selection(3, 1, 5, 2), + [ + 'open block', + indentation + 'let a = 10', + closingBracket + 'end block', + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + ], + new Selection(4, 1, 6, 2) + ); + }); + }); + }); + + test('move lines down enter empty block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + 'open block' + openBracket, + 'end block', + ], + new Selection(1, 1, 3, 2), + [ + 'open block' + openBracket, + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + 'end block', + ], + new Selection(2, 1, 4, 2) + ); + }); + }); + }); + + test('move lines down leave empty block', function () { + closingBlockChars.forEach((closingBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block', + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + closingBracket + 'end block', + ], + new Selection(2, 1, 4, 2), + [ + 'open block', + closingBracket + 'end block', + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + ], + new Selection(3, 1, 5, 2) + ); + }); + }); + }); + + test('move lines up enter block', function () { + closingBlockChars.forEach((closingBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block', + indentation + 'let a = 10', + closingBracket + 'end block', + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + ], + new Selection(4, 1, 6, 2), + [ + 'open block', + indentation + 'let a = 10', + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + closingBracket + 'end block', + ], + new Selection(3, 1, 5, 2) + ); + }); + }); + }); + + test('move lines up leave block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block' + openBracket, + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + indentation + 'let a = 10', + 'end block', + ], + new Selection(2, 1, 4, 2), + [ + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + 'open block' + openBracket, + indentation + 'let a = 10', + 'end block', + ], + new Selection(1, 1, 3, 2) + ); + }); + }); + }); + + test('move lines up enter empty block', function () { + closingBlockChars.forEach((closingBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block', + closingBracket + ' end block', + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + ], + new Selection(3, 1, 5, 2), + [ + 'open block', + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + closingBracket + ' end block', + ], + new Selection(2, 1, 4, 2) + ); + }); + }); + }); + + test('move lines up leave empty block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + 'open block' + openBracket, + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + 'end block', + ], + new Selection(2, 1, 4, 2), + [ + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + 'open block' + openBracket, + 'end block', + ], + new Selection(1, 1, 3, 2) + ); + }); + }); + }); + + test('move lines up through empty line', function () { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommand( + [ + indentation + 'another line', + '', + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + ], + new Selection(3, 1, 5, 2), + [ + indentation + 'another line', + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + '', + ], + new Selection(2, 1, 4, 2) + ); + }); + }); + + test('move lines down through empty line', function () { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommand( + [ + indentation + 'another line', + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + '', + ], + new Selection(2, 1, 4, 2), + [ + indentation + 'another line', + '', + indentation + 'blocktomove start', + indentation + indentation + 'blocktomove middle', + indentation + 'blocktomove end', + ], + new Selection(3, 1, 5, 2) + ); + }); + }); + + test('move line up leave commented block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + lineComment + 'open block' + openBracket, + 'line to move', + ], + new Selection(2, 1, 2, 2), + [ + 'line to move', + lineComment + 'open block' + openBracket, + ], + new Selection(1, 1, 1, 2) + ); + }); + }); + }); + + test('move lines up leave commented block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + lineComment + 'open block' + openBracket, + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + ], + new Selection(2, 1, 4, 2), + [ + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + lineComment + 'open block' + openBracket, + ], + new Selection(1, 1, 3, 2) + ); + }); + }); + }); + + test('move line up enter commented block', function () { + closingBlockChars.forEach((closeBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + lineComment + closeBracket + 'close block', + 'line to move', + ], + new Selection(2, 1, 2, 2), + [ + 'line to move', + lineComment + closeBracket + 'close block', + ], + new Selection(1, 1, 1, 2) + ); + }); + }); + }); + + test('move lines up enter commented block', function () { + closingBlockChars.forEach((closeBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesUpCommandWithAndWithoutPreindentation( + indentation, + [ + lineComment + closeBracket + 'close block', + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + ], + new Selection(2, 1, 4, 2), + [ + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + lineComment + closeBracket + 'close block', + ], + new Selection(1, 1, 3, 2) + ); + }); + }); + }); + + test('move line down enter commented block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'line to move', + lineComment + 'open block' + openBracket, + ], + new Selection(1, 1, 1, 2), + [ + lineComment + 'open block' + openBracket, + 'line to move', + ], + new Selection(2, 1, 2, 2) + ); + }); + }); + }); + + test('move lines down enter commented block', function () { + openBlockChars.forEach((openBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + lineComment + 'open block' + openBracket, + ], + new Selection(1, 1, 3, 2), + [ + lineComment + 'open block' + openBracket, + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + ], + new Selection(2, 1, 4, 2) + ); + }); + }); + }); + + test('move line down leave commented block', function () { + closingBlockChars.forEach((closeBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'line to move', + lineComment + ' ' + closeBracket, + ], + new Selection(1, 1, 1, 2), + [ + lineComment + ' ' + closeBracket, + 'line to move', + ], + new Selection(2, 1, 2, 2) + ); + }); + }); + }); + + test('move lines down leave commented block', function () { + closingBlockChars.forEach((closeBracket: string) => { + indentationType.forEach((indentation: string) => { + testMoveLinesDownCommandWithAndWithoutPreindentation( + indentation, + [ + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + lineComment + ' ' + closeBracket, + ], + new Selection(1, 1, 3, 2), + [ + lineComment + ' ' + closeBracket, + 'blocktomove start', + indentation + 'blocktomove middle', + 'blocktomove end', + ], + new Selection(2, 1, 4, 2) + ); + }); + }); + }); + }); + diff --git a/src/vs/editor/test/common/commands/commandTestUtils.ts b/src/vs/editor/test/common/commands/commandTestUtils.ts index 94d078b007379..91b2d3192f1c4 100644 --- a/src/vs/editor/test/common/commands/commandTestUtils.ts +++ b/src/vs/editor/test/common/commands/commandTestUtils.ts @@ -20,10 +20,11 @@ export function testCommand( selection: Selection, commandFactory: (selection: Selection) => editorCommon.ICommand, expectedLines: string[], - expectedSelection: Selection + expectedSelection: Selection, + options: editorCommon.ITextModelCreationOptions = undefined ): void { - let model = Model.createFromString(lines.join('\n'), undefined, languageIdentifier); + let model = Model.createFromString(lines.join('\n'), options, languageIdentifier); let config = new TestConfiguration(null); let cursor = new Cursor(config, model, viewModelHelper(model), false); @@ -87,3 +88,4 @@ export function createInsertDeleteSingleEditOp(text: string, positionLineNumber: forceMoveMarkers: true }; } +