From 7cfc1943529a064f9986f99a6bf2f1c4e01e4a1c Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Wed, 15 Jan 2020 11:12:55 +0100 Subject: [PATCH] Fixes #85712 --- .../editor/common/commands/replaceCommand.ts | 6 +- src/vs/editor/common/controller/cursor.ts | 10 +- .../common/controller/cursorTypeOperations.ts | 2 +- src/vs/editor/common/editorCommon.ts | 4 +- .../test/linesOperations.test.ts | 304 +++++++++--------- .../browser/commands/shiftCommand.test.ts | 3 +- .../trimTrailingWhitespaceCommand.test.ts | 3 +- .../test/browser/controller/cursor.test.ts | 26 +- src/vs/editor/test/browser/testCommand.ts | 10 +- src/vs/monaco.d.ts | 4 +- 10 files changed, 206 insertions(+), 166 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 4ae44cf28c1..3e628f2db76 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -122,17 +122,19 @@ export class ReplaceCommandThatPreservesSelection implements ICommand { private readonly _range: Range; private readonly _text: string; private readonly _initialSelection: Selection; + private readonly _forceMoveMarkers: boolean; private _selectionId: string | null; - constructor(editRange: Range, text: string, initialSelection: Selection) { + constructor(editRange: Range, text: string, initialSelection: Selection, forceMoveMarkers: boolean = false) { this._range = editRange; this._text = text; this._initialSelection = initialSelection; + this._forceMoveMarkers = forceMoveMarkers; this._selectionId = null; } public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { - builder.addEditOperation(this._range, this._text); + builder.addTrackedEditOperation(this._range, this._text, this._forceMoveMarkers); this._selectionId = builder.trackSelection(this._initialSelection); } diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts index 80e20c21d7f..79fa0e5ff5b 100644 --- a/src/vs/editor/common/controller/cursor.ts +++ b/src/vs/editor/common/controller/cursor.ts @@ -727,7 +727,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { case H.Paste: cursorChangeReason = CursorChangeReason.Paste; - this._paste(payload.text, payload.pasteOnNewLine, payload.multicursorText); + this._paste(payload.text, payload.pasteOnNewLine, payload.multicursorText || []); break; case H.Cut: @@ -1000,7 +1000,7 @@ class CommandExecutor { let operations: IIdentifiedSingleEditOperation[] = []; let operationMinor = 0; - const addEditOperation = (selection: Range, text: string | null) => { + const addEditOperation = (selection: Range, text: string | null, forceMoveMarkers: boolean = false) => { if (selection.isEmpty() && text === '') { // This command wants to add a no-op => no thank you return; @@ -1012,15 +1012,15 @@ class CommandExecutor { }, range: selection, text: text, - forceMoveMarkers: false, + forceMoveMarkers: forceMoveMarkers, isAutoWhitespaceEdit: command.insertsAutoWhitespace }); }; let hadTrackedEditOperation = false; - const addTrackedEditOperation = (selection: Range, text: string | null) => { + const addTrackedEditOperation = (selection: Range, text: string | null, forceMoveMarkers?: boolean) => { hadTrackedEditOperation = true; - addEditOperation(selection, text); + addEditOperation(selection, text, forceMoveMarkers); }; const trackSelection = (selection: Selection, trackPreviousOnEmpty?: boolean) => { diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index d9ef5f66191..aab378176b7 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -94,7 +94,7 @@ export class TypeOperations { if (pasteOnNewLine) { // Paste entire line at the beginning of line let typeSelection = new Range(position.lineNumber, 1, position.lineNumber, 1); - commands[i] = new ReplaceCommandThatPreservesSelection(typeSelection, text, selection); + commands[i] = new ReplaceCommandThatPreservesSelection(typeSelection, text, selection, true); } else { commands[i] = new ReplaceCommand(selection, text); } diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 679cb676023..946d24472a8 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -22,7 +22,7 @@ export interface IEditOperationBuilder { * @param range The range to replace (delete). May be empty to represent a simple insert. * @param text The text to replace with. May be null to represent a simple delete. */ - addEditOperation(range: Range, text: string | null): void; + addEditOperation(range: Range, text: string | null, forceMoveMarkers?: boolean): void; /** * Add a new edit operation (a replace operation). @@ -30,7 +30,7 @@ export interface IEditOperationBuilder { * @param range The range to replace (delete). May be empty to represent a simple insert. * @param text The text to replace with. May be null to represent a simple delete. */ - addTrackedEditOperation(range: Range, text: string | null): void; + addTrackedEditOperation(range: Range, text: string | null, forceMoveMarkers?: boolean): void; /** * Track `selection` when applying edit operations. diff --git a/src/vs/editor/contrib/linesOperations/test/linesOperations.test.ts b/src/vs/editor/contrib/linesOperations/test/linesOperations.test.ts index 58663215088..64b26b23b76 100644 --- a/src/vs/editor/contrib/linesOperations/test/linesOperations.test.ts +++ b/src/vs/editor/contrib/linesOperations/test/linesOperations.test.ts @@ -12,6 +12,19 @@ import { ITextModel } from 'vs/editor/common/model'; import { TitleCaseAction, DeleteAllLeftAction, DeleteAllRightAction, IndentLinesAction, InsertLineAfterAction, InsertLineBeforeAction, JoinLinesAction, LowerCaseAction, SortLinesAscendingAction, SortLinesDescendingAction, TransposeAction, UpperCaseAction, DeleteLinesAction } from 'vs/editor/contrib/linesOperations/linesOperations'; import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { createTextModel } from 'vs/editor/test/common/editorTestUtils'; +import type { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { EditorAction } from 'vs/editor/browser/editorExtensions'; + +function assertSelection(editor: ICodeEditor, expected: Selection | Selection[]): void { + if (!Array.isArray(expected)) { + expected = [expected]; + } + assert.deepEqual(editor.getSelections(), expected); +} + +function executeAction(action: EditorAction, editor: ICodeEditor): void { + action.run(null!, editor, undefined); +} suite('Editor Contrib - Line Operations', () => { suite('SortLinesAscendingAction', () => { @@ -26,13 +39,13 @@ suite('Editor Contrib - Line Operations', () => { let sortLinesAscendingAction = new SortLinesAscendingAction(); editor.setSelection(new Selection(1, 1, 3, 5)); - sortLinesAscendingAction.run(null!, editor); + executeAction(sortLinesAscendingAction, editor); assert.deepEqual(model.getLinesContent(), [ 'alpha', 'beta', 'omicron' ]); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 3, 7).toString()); + assertSelection(editor, new Selection(1, 1, 3, 7)); }); }); @@ -51,7 +64,7 @@ suite('Editor Contrib - Line Operations', () => { let sortLinesAscendingAction = new SortLinesAscendingAction(); editor.setSelections([new Selection(1, 1, 3, 5), new Selection(5, 1, 7, 5)]); - sortLinesAscendingAction.run(null!, editor); + executeAction(sortLinesAscendingAction, editor); assert.deepEqual(model.getLinesContent(), [ 'alpha', 'beta', @@ -84,13 +97,13 @@ suite('Editor Contrib - Line Operations', () => { let sortLinesDescendingAction = new SortLinesDescendingAction(); editor.setSelection(new Selection(1, 1, 3, 7)); - sortLinesDescendingAction.run(null!, editor); + executeAction(sortLinesDescendingAction, editor); assert.deepEqual(model.getLinesContent(), [ 'omicron', 'beta', 'alpha' ]); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 3, 5).toString()); + assertSelection(editor, new Selection(1, 1, 3, 5)); }); }); @@ -109,7 +122,7 @@ suite('Editor Contrib - Line Operations', () => { let sortLinesDescendingAction = new SortLinesDescendingAction(); editor.setSelections([new Selection(1, 1, 3, 7), new Selection(5, 1, 7, 7)]); - sortLinesDescendingAction.run(null!, editor); + executeAction(sortLinesDescendingAction, editor); assert.deepEqual(model.getLinesContent(), [ 'omicron', 'beta', @@ -143,13 +156,13 @@ suite('Editor Contrib - Line Operations', () => { let deleteAllLeftAction = new DeleteAllLeftAction(); editor.setSelection(new Selection(1, 2, 1, 2)); - deleteAllLeftAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'ne', '001'); + executeAction(deleteAllLeftAction, editor); + assert.equal(model.getLineContent(1), 'ne'); editor.setSelections([new Selection(2, 2, 2, 2), new Selection(3, 2, 3, 2)]); - deleteAllLeftAction.run(null!, editor); - assert.equal(model.getLineContent(2), 'wo', '002'); - assert.equal(model.getLineContent(3), 'hree', '003'); + executeAction(deleteAllLeftAction, editor); + assert.equal(model.getLineContent(2), 'wo'); + assert.equal(model.getLineContent(3), 'hree'); }); }); @@ -164,16 +177,16 @@ suite('Editor Contrib - Line Operations', () => { let deleteAllLeftAction = new DeleteAllLeftAction(); editor.setSelection(new Selection(2, 1, 2, 1)); - deleteAllLeftAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'onetwo', '001'); + executeAction(deleteAllLeftAction, editor); + assert.equal(model.getLineContent(1), 'onetwo'); editor.setSelections([new Selection(1, 1, 1, 1), new Selection(2, 1, 2, 1)]); - deleteAllLeftAction.run(null!, editor); + executeAction(deleteAllLeftAction, editor); assert.equal(model.getLinesContent()[0], 'onetwothree'); assert.equal(model.getLinesContent().length, 1); editor.setSelection(new Selection(1, 1, 1, 1)); - deleteAllLeftAction.run(null!, editor); + executeAction(deleteAllLeftAction, editor); assert.equal(model.getLinesContent()[0], 'onetwothree'); }); }); @@ -197,7 +210,7 @@ suite('Editor Contrib - Line Operations', () => { editor.setSelections([beforeSecondWasoSelection, endOfBCCSelection, endOfNonono]); - deleteAllLeftAction.run(null!, editor); + executeAction(deleteAllLeftAction, editor); let selections = editor.getSelections()!; assert.equal(model.getLineContent(2), ''); @@ -225,7 +238,7 @@ suite('Editor Contrib - Line Operations', () => { selections[2].endColumn ], [5, 1, 5, 1]); - deleteAllLeftAction.run(null!, editor); + executeAction(deleteAllLeftAction, editor); selections = editor.getSelections()!; assert.equal(model.getLineContent(1), 'hi my name is Carlos Matos waso waso'); @@ -263,24 +276,24 @@ suite('Editor Contrib - Line Operations', () => { let deleteAllLeftAction = new DeleteAllLeftAction(); editor.setSelections([new Selection(1, 2, 1, 2), new Selection(1, 4, 1, 4)]); - deleteAllLeftAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'lo', '001'); + executeAction(deleteAllLeftAction, editor); + assert.equal(model.getLineContent(1), 'lo'); editor.setSelections([new Selection(2, 2, 2, 2), new Selection(2, 4, 2, 5)]); - deleteAllLeftAction.run(null!, editor); - assert.equal(model.getLineContent(2), 'd', '002'); + executeAction(deleteAllLeftAction, editor); + assert.equal(model.getLineContent(2), 'd'); editor.setSelections([new Selection(3, 2, 3, 5), new Selection(3, 7, 3, 7)]); - deleteAllLeftAction.run(null!, editor); - assert.equal(model.getLineContent(3), 'world', '003'); + executeAction(deleteAllLeftAction, editor); + assert.equal(model.getLineContent(3), 'world'); editor.setSelections([new Selection(4, 3, 4, 3), new Selection(4, 5, 5, 4)]); - deleteAllLeftAction.run(null!, editor); - assert.equal(model.getLineContent(4), 'jour', '004'); + executeAction(deleteAllLeftAction, editor); + assert.equal(model.getLineContent(4), 'jour'); editor.setSelections([new Selection(5, 3, 6, 3), new Selection(6, 5, 7, 5), new Selection(7, 7, 7, 7)]); - deleteAllLeftAction.run(null!, editor); - assert.equal(model.getLineContent(5), 'world', '005'); + executeAction(deleteAllLeftAction, editor); + assert.equal(model.getLineContent(5), 'world'); }); }); @@ -300,7 +313,7 @@ suite('Editor Contrib - Line Operations', () => { assert.equal(model.getLineContent(1), 'Typing some text here on line one'); assert.deepEqual(editor.getSelection(), new Selection(1, 31, 1, 31)); - deleteAllLeftAction.run(null!, editor); + executeAction(deleteAllLeftAction, editor); assert.equal(model.getLineContent(1), 'one'); assert.deepEqual(editor.getSelection(), new Selection(1, 1, 1, 1)); @@ -331,29 +344,29 @@ suite('Editor Contrib - Line Operations', () => { let joinLinesAction = new JoinLinesAction(); editor.setSelection(new Selection(1, 2, 1, 2)); - joinLinesAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'hello world', '001'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 6, 1, 6).toString(), '002'); + executeAction(joinLinesAction, editor); + assert.equal(model.getLineContent(1), 'hello world'); + assertSelection(editor, new Selection(1, 6, 1, 6)); editor.setSelection(new Selection(2, 2, 2, 2)); - joinLinesAction.run(null!, editor); - assert.equal(model.getLineContent(2), 'hello world', '003'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 7, 2, 7).toString(), '004'); + executeAction(joinLinesAction, editor); + assert.equal(model.getLineContent(2), 'hello world'); + assertSelection(editor, new Selection(2, 7, 2, 7)); editor.setSelection(new Selection(3, 2, 3, 2)); - joinLinesAction.run(null!, editor); - assert.equal(model.getLineContent(3), 'hello world', '005'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(3, 7, 3, 7).toString(), '006'); + executeAction(joinLinesAction, editor); + assert.equal(model.getLineContent(3), 'hello world'); + assertSelection(editor, new Selection(3, 7, 3, 7)); editor.setSelection(new Selection(4, 2, 5, 3)); - joinLinesAction.run(null!, editor); - assert.equal(model.getLineContent(4), 'hello world', '007'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(4, 2, 4, 8).toString(), '008'); + executeAction(joinLinesAction, editor); + assert.equal(model.getLineContent(4), 'hello world'); + assertSelection(editor, new Selection(4, 2, 4, 8)); editor.setSelection(new Selection(5, 1, 7, 3)); - joinLinesAction.run(null!, editor); - assert.equal(model.getLineContent(5), 'hello world', '009'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(5, 1, 5, 3).toString(), '010'); + executeAction(joinLinesAction, editor); + assert.equal(model.getLineContent(5), 'hello world'); + assertSelection(editor, new Selection(5, 1, 5, 3)); }); }); @@ -367,10 +380,10 @@ suite('Editor Contrib - Line Operations', () => { let joinLinesAction = new JoinLinesAction(); editor.setSelection(new Selection(2, 1, 2, 1)); - joinLinesAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'hello', '001'); - assert.equal(model.getLineContent(2), 'world', '002'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 6, 2, 6).toString(), '003'); + executeAction(joinLinesAction, editor); + assert.equal(model.getLineContent(1), 'hello'); + assert.equal(model.getLineContent(2), 'world'); + assertSelection(editor, new Selection(2, 6, 2, 6)); }); }); @@ -402,19 +415,16 @@ suite('Editor Contrib - Line Operations', () => { new Selection(10, 1, 10, 1) ]); - joinLinesAction.run(null!, editor); - assert.equal(model.getLinesContent().join('\n'), 'hello world\nhello world\nhello world\nhello world\n\nhello world', '001'); - assert.deepEqual(editor.getSelections()!.toString(), [ + executeAction(joinLinesAction, editor); + assert.equal(model.getLinesContent().join('\n'), 'hello world\nhello world\nhello world\nhello world\n\nhello world'); + assertSelection(editor, [ /** primary cursor */ new Selection(3, 4, 3, 8), new Selection(1, 6, 1, 6), new Selection(2, 2, 2, 8), new Selection(4, 5, 4, 9), new Selection(6, 1, 6, 1) - ].toString(), '002'); - - /** primary cursor */ - assert.deepEqual(editor.getSelection()!.toString(), new Selection(3, 4, 3, 8).toString(), '003'); + ]); }); }); @@ -433,7 +443,7 @@ suite('Editor Contrib - Line Operations', () => { assert.equal(model.getLineContent(1), 'hello my dear'); assert.deepEqual(editor.getSelection(), new Selection(1, 14, 1, 14)); - joinLinesAction.run(null!, editor); + executeAction(joinLinesAction, editor); assert.equal(model.getLineContent(1), 'hello my dear world'); assert.deepEqual(editor.getSelection(), new Selection(1, 14, 1, 14)); @@ -456,29 +466,29 @@ suite('Editor Contrib - Line Operations', () => { let transposeAction = new TransposeAction(); editor.setSelection(new Selection(1, 1, 1, 1)); - transposeAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'hello world', '001'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 2, 1, 2).toString(), '002'); + executeAction(transposeAction, editor); + assert.equal(model.getLineContent(1), 'hello world'); + assertSelection(editor, new Selection(1, 2, 1, 2)); editor.setSelection(new Selection(1, 6, 1, 6)); - transposeAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'hell oworld', '003'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 7, 1, 7).toString(), '004'); + executeAction(transposeAction, editor); + assert.equal(model.getLineContent(1), 'hell oworld'); + assertSelection(editor, new Selection(1, 7, 1, 7)); editor.setSelection(new Selection(1, 12, 1, 12)); - transposeAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'hell oworl', '005'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 2, 2, 2).toString(), '006'); + executeAction(transposeAction, editor); + assert.equal(model.getLineContent(1), 'hell oworl'); + assertSelection(editor, new Selection(2, 2, 2, 2)); editor.setSelection(new Selection(3, 1, 3, 1)); - transposeAction.run(null!, editor); - assert.equal(model.getLineContent(3), '', '007'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(4, 1, 4, 1).toString(), '008'); + executeAction(transposeAction, editor); + assert.equal(model.getLineContent(3), ''); + assertSelection(editor, new Selection(4, 1, 4, 1)); editor.setSelection(new Selection(4, 2, 4, 2)); - transposeAction.run(null!, editor); - assert.equal(model.getLineContent(4), ' ', '009'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(4, 3, 4, 3).toString(), '010'); + executeAction(transposeAction, editor); + assert.equal(model.getLineContent(4), ' '); + assertSelection(editor, new Selection(4, 3, 4, 3)); } ); @@ -498,24 +508,24 @@ suite('Editor Contrib - Line Operations', () => { let transposeAction = new TransposeAction(); editor.setSelection(new Selection(1, 1, 1, 1)); - transposeAction.run(null!, editor); - assert.equal(model.getLineContent(2), '', '011'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 1, 2, 1).toString(), '012'); + executeAction(transposeAction, editor); + assert.equal(model.getLineContent(2), ''); + assertSelection(editor, new Selection(2, 1, 2, 1)); editor.setSelection(new Selection(3, 6, 3, 6)); - transposeAction.run(null!, editor); - assert.equal(model.getLineContent(4), 'oworld', '013'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(4, 2, 4, 2).toString(), '014'); + executeAction(transposeAction, editor); + assert.equal(model.getLineContent(4), 'oworld'); + assertSelection(editor, new Selection(4, 2, 4, 2)); editor.setSelection(new Selection(6, 12, 6, 12)); - transposeAction.run(null!, editor); - assert.equal(model.getLineContent(7), 'd', '015'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(7, 2, 7, 2).toString(), '016'); + executeAction(transposeAction, editor); + assert.equal(model.getLineContent(7), 'd'); + assertSelection(editor, new Selection(7, 2, 7, 2)); editor.setSelection(new Selection(8, 12, 8, 12)); - transposeAction.run(null!, editor); - assert.equal(model.getLineContent(8), 'hello world', '019'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(8, 12, 8, 12).toString(), '020'); + executeAction(transposeAction, editor); + assert.equal(model.getLineContent(8), 'hello world'); + assertSelection(editor, new Selection(8, 12, 8, 12)); } ); }); @@ -532,44 +542,44 @@ suite('Editor Contrib - Line Operations', () => { let titlecaseAction = new TitleCaseAction(); editor.setSelection(new Selection(1, 1, 1, 12)); - uppercaseAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'HELLO WORLD', '001'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 12).toString(), '002'); + executeAction(uppercaseAction, editor); + assert.equal(model.getLineContent(1), 'HELLO WORLD'); + assertSelection(editor, new Selection(1, 1, 1, 12)); editor.setSelection(new Selection(1, 1, 1, 12)); - lowercaseAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'hello world', '003'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 12).toString(), '004'); + executeAction(lowercaseAction, editor); + assert.equal(model.getLineContent(1), 'hello world'); + assertSelection(editor, new Selection(1, 1, 1, 12)); editor.setSelection(new Selection(1, 3, 1, 3)); - uppercaseAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'HELLO world', '005'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 3, 1, 3).toString(), '006'); + executeAction(uppercaseAction, editor); + assert.equal(model.getLineContent(1), 'HELLO world'); + assertSelection(editor, new Selection(1, 3, 1, 3)); editor.setSelection(new Selection(1, 4, 1, 4)); - lowercaseAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'hello world', '007'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 4, 1, 4).toString(), '008'); + executeAction(lowercaseAction, editor); + assert.equal(model.getLineContent(1), 'hello world'); + assertSelection(editor, new Selection(1, 4, 1, 4)); editor.setSelection(new Selection(1, 1, 1, 12)); - titlecaseAction.run(null!, editor); - assert.equal(model.getLineContent(1), 'Hello World', '009'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 12).toString(), '010'); + executeAction(titlecaseAction, editor); + assert.equal(model.getLineContent(1), 'Hello World'); + assertSelection(editor, new Selection(1, 1, 1, 12)); editor.setSelection(new Selection(2, 1, 2, 6)); - uppercaseAction.run(null!, editor); - assert.equal(model.getLineContent(2), 'ÖÇŞĞÜ', '011'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 1, 2, 6).toString(), '012'); + executeAction(uppercaseAction, editor); + assert.equal(model.getLineContent(2), 'ÖÇŞĞÜ'); + assertSelection(editor, new Selection(2, 1, 2, 6)); editor.setSelection(new Selection(2, 1, 2, 6)); - lowercaseAction.run(null!, editor); - assert.equal(model.getLineContent(2), 'öçşğü', '013'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 1, 2, 6).toString(), '014'); + executeAction(lowercaseAction, editor); + assert.equal(model.getLineContent(2), 'öçşğü'); + assertSelection(editor, new Selection(2, 1, 2, 6)); editor.setSelection(new Selection(2, 1, 2, 6)); - titlecaseAction.run(null!, editor); - assert.equal(model.getLineContent(2), 'Öçşğü', '015'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 1, 2, 6).toString(), '016'); + executeAction(titlecaseAction, editor); + assert.equal(model.getLineContent(2), 'Öçşğü'); + assertSelection(editor, new Selection(2, 1, 2, 6)); } ); @@ -586,27 +596,27 @@ suite('Editor Contrib - Line Operations', () => { let titlecaseAction = new TitleCaseAction(); editor.setSelection(new Selection(1, 1, 1, 12)); - titlecaseAction.run(null!, editor); + executeAction(titlecaseAction, editor); assert.equal(model.getLineContent(1), 'Foo Bar Baz'); editor.setSelection(new Selection(2, 1, 2, 12)); - titlecaseAction.run(null!, editor); + executeAction(titlecaseAction, editor); assert.equal(model.getLineContent(2), 'Foo\'Bar\'Baz'); editor.setSelection(new Selection(3, 1, 3, 12)); - titlecaseAction.run(null!, editor); + executeAction(titlecaseAction, editor); assert.equal(model.getLineContent(3), 'Foo[Bar]Baz'); editor.setSelection(new Selection(4, 1, 4, 12)); - titlecaseAction.run(null!, editor); + executeAction(titlecaseAction, editor); assert.equal(model.getLineContent(4), 'Foo`Bar~Baz'); editor.setSelection(new Selection(5, 1, 5, 12)); - titlecaseAction.run(null!, editor); + executeAction(titlecaseAction, editor); assert.equal(model.getLineContent(5), 'Foo^Bar%Baz'); editor.setSelection(new Selection(6, 1, 6, 12)); - titlecaseAction.run(null!, editor); + executeAction(titlecaseAction, editor); assert.equal(model.getLineContent(6), 'Foo$Bar!Baz'); } ); @@ -621,24 +631,24 @@ suite('Editor Contrib - Line Operations', () => { let lowercaseAction = new LowerCaseAction(); editor.setSelection(new Selection(1, 1, 1, 1)); - uppercaseAction.run(null!, editor); - assert.equal(model.getLineContent(1), '', '013'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 1).toString(), '014'); + executeAction(uppercaseAction, editor); + assert.equal(model.getLineContent(1), ''); + assertSelection(editor, new Selection(1, 1, 1, 1)); editor.setSelection(new Selection(1, 1, 1, 1)); - lowercaseAction.run(null!, editor); - assert.equal(model.getLineContent(1), '', '015'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 1).toString(), '016'); + executeAction(lowercaseAction, editor); + assert.equal(model.getLineContent(1), ''); + assertSelection(editor, new Selection(1, 1, 1, 1)); editor.setSelection(new Selection(2, 2, 2, 2)); - uppercaseAction.run(null!, editor); - assert.equal(model.getLineContent(2), ' ', '017'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 2, 2, 2).toString(), '018'); + executeAction(uppercaseAction, editor); + assert.equal(model.getLineContent(2), ' '); + assertSelection(editor, new Selection(2, 2, 2, 2)); editor.setSelection(new Selection(2, 2, 2, 2)); - lowercaseAction.run(null!, editor); - assert.equal(model.getLineContent(2), ' ', '019'); - assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 2, 2, 2).toString(), '020'); + executeAction(lowercaseAction, editor); + assert.equal(model.getLineContent(2), ' '); + assertSelection(editor, new Selection(2, 2, 2, 2)); } ); }); @@ -649,17 +659,17 @@ suite('Editor Contrib - Line Operations', () => { const model = editor.getModel()!; const action = new DeleteAllRightAction(); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['']); assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]); editor.setSelection(new Selection(1, 1, 1, 1)); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['']); assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]); editor.setSelections([new Selection(1, 1, 1, 1), new Selection(1, 1, 1, 1), new Selection(1, 1, 1, 1)]); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['']); assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]); }); @@ -674,17 +684,17 @@ suite('Editor Contrib - Line Operations', () => { const action = new DeleteAllRightAction(); editor.setSelection(new Selection(1, 2, 1, 5)); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['ho', 'world']); assert.deepEqual(editor.getSelections(), [new Selection(1, 2, 1, 2)]); editor.setSelection(new Selection(1, 1, 2, 4)); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['ld']); assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]); editor.setSelection(new Selection(1, 1, 1, 3)); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['']); assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]); }); @@ -699,12 +709,12 @@ suite('Editor Contrib - Line Operations', () => { const action = new DeleteAllRightAction(); editor.setSelection(new Selection(1, 3, 1, 3)); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['he', 'world']); assert.deepEqual(editor.getSelections(), [new Selection(1, 3, 1, 3)]); editor.setSelection(new Selection(2, 1, 2, 1)); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['he', '']); assert.deepEqual(editor.getSelections(), [new Selection(2, 1, 2, 1)]); }); @@ -719,17 +729,17 @@ suite('Editor Contrib - Line Operations', () => { const action = new DeleteAllRightAction(); editor.setSelection(new Selection(1, 6, 1, 6)); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['helloworld']); assert.deepEqual(editor.getSelections(), [new Selection(1, 6, 1, 6)]); editor.setSelection(new Selection(1, 6, 1, 6)); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['hello']); assert.deepEqual(editor.getSelections(), [new Selection(1, 6, 1, 6)]); editor.setSelection(new Selection(1, 6, 1, 6)); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['hello']); assert.deepEqual(editor.getSelections(), [new Selection(1, 6, 1, 6)]); }); @@ -749,34 +759,34 @@ suite('Editor Contrib - Line Operations', () => { new Selection(1, 6, 1, 6), new Selection(3, 4, 3, 4), ]); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['hethere', 'wor']); assert.deepEqual(editor.getSelections(), [ new Selection(1, 3, 1, 3), new Selection(2, 4, 2, 4) ]); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['he', 'wor']); assert.deepEqual(editor.getSelections(), [ new Selection(1, 3, 1, 3), new Selection(2, 4, 2, 4) ]); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['hewor']); assert.deepEqual(editor.getSelections(), [ new Selection(1, 3, 1, 3), new Selection(1, 6, 1, 6) ]); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['he']); assert.deepEqual(editor.getSelections(), [ new Selection(1, 3, 1, 3) ]); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['he']); assert.deepEqual(editor.getSelections(), [ new Selection(1, 3, 1, 3) @@ -798,7 +808,7 @@ suite('Editor Contrib - Line Operations', () => { new Selection(1, 6, 1, 6), new Selection(3, 4, 3, 4), ]); - action.run(null!, editor); + executeAction(action, editor); assert.deepEqual(model.getLinesContent(), ['hethere', 'wor']); assert.deepEqual(editor.getSelections(), [ new Selection(1, 3, 1, 3), @@ -831,7 +841,7 @@ suite('Editor Contrib - Line Operations', () => { editor.setPosition(new Position(lineNumber, column)); let insertLineBeforeAction = new InsertLineBeforeAction(); - insertLineBeforeAction.run(null!, editor); + executeAction(insertLineBeforeAction, editor); callback(editor.getModel()!, cursor); }); } @@ -872,7 +882,7 @@ suite('Editor Contrib - Line Operations', () => { editor.setPosition(new Position(lineNumber, column)); let insertLineAfterAction = new InsertLineAfterAction(); - insertLineAfterAction.run(null!, editor); + executeAction(insertLineAfterAction, editor); callback(editor.getModel()!, cursor); }); } @@ -917,7 +927,7 @@ suite('Editor Contrib - Line Operations', () => { let indentLinesAction = new IndentLinesAction(); editor.setPosition(new Position(1, 2)); - indentLinesAction.run(null!, editor); + executeAction(indentLinesAction, editor); assert.equal(model.getLineContent(1), '\tfunction baz() {'); assert.deepEqual(editor.getSelection(), new Selection(1, 3, 1, 3)); @@ -942,7 +952,7 @@ suite('Editor Contrib - Line Operations', () => { const indentLinesAction = new IndentLinesAction(); editor.setPosition(new Position(1, 1)); - indentLinesAction.run(null!, editor); + executeAction(indentLinesAction, editor); assert.equal(model.getLineContent(1), '\tSome text'); assert.deepEqual(editor.getSelection(), new Selection(1, 2, 1, 2)); }); @@ -964,7 +974,7 @@ suite('Editor Contrib - Line Operations', () => { new Selection(3, 4, 3, 4), ]); const deleteLinesAction = new DeleteLinesAction(); - deleteLinesAction.run(null!, editor); + executeAction(deleteLinesAction, editor); assert.equal(editor.getValue(), 'a\nc'); }); @@ -976,7 +986,7 @@ suite('Editor Contrib - Line Operations', () => { withTestCodeEditor(initialText, {}, (editor) => { editor.setSelections(initialSelections); const deleteLinesAction = new DeleteLinesAction(); - deleteLinesAction.run(null!, editor); + executeAction(deleteLinesAction, editor); assert.equal(editor.getValue(), resultingText.join('\n')); assert.deepEqual(editor.getSelections(), resultingSelections); diff --git a/src/vs/editor/test/browser/commands/shiftCommand.test.ts b/src/vs/editor/test/browser/commands/shiftCommand.test.ts index da26bb2030c..0a6ada7efbf 100644 --- a/src/vs/editor/test/browser/commands/shiftCommand.test.ts +++ b/src/vs/editor/test/browser/commands/shiftCommand.test.ts @@ -22,7 +22,8 @@ import { EditorAutoIndentStrategy } from 'vs/editor/common/config/editorOptions' export function createSingleEditOp(text: string, positionLineNumber: number, positionColumn: number, selectionLineNumber: number = positionLineNumber, selectionColumn: number = positionColumn): IIdentifiedSingleEditOperation { return { range: new Range(selectionLineNumber, selectionColumn, positionLineNumber, positionColumn), - text: text + text: text, + forceMoveMarkers: false }; } diff --git a/src/vs/editor/test/browser/commands/trimTrailingWhitespaceCommand.test.ts b/src/vs/editor/test/browser/commands/trimTrailingWhitespaceCommand.test.ts index bf414fa1503..af0c64e537c 100644 --- a/src/vs/editor/test/browser/commands/trimTrailingWhitespaceCommand.test.ts +++ b/src/vs/editor/test/browser/commands/trimTrailingWhitespaceCommand.test.ts @@ -28,7 +28,8 @@ function createInsertDeleteSingleEditOp(text: string | null, positionLineNumber: export function createSingleEditOp(text: string | null, positionLineNumber: number, positionColumn: number, selectionLineNumber: number = positionLineNumber, selectionColumn: number = positionColumn): IIdentifiedSingleEditOperation { return { range: new Range(selectionLineNumber, selectionColumn, positionLineNumber, positionColumn), - text: text + text: text, + forceMoveMarkers: false }; } diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 7b9cafb8c95..0f300688e23 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -2279,6 +2279,30 @@ suite('Editor Controller - Regression tests', () => { model.dispose(); }); + + test('issue #85712: Paste line moves cursor to start of current line rather than start of next line', () => { + let model = createTextModel( + [ + 'abc123', + '' + ].join('\n') + ); + + withTestCodeEditor(null, { model: model }, (editor, cursor) => { + editor.setSelections([ + new Selection(2, 1, 2, 1) + ]); + cursorCommand(cursor, H.Paste, { text: 'something\n', pasteOnNewLine: true }); + assert.equal(model.getValue(), [ + 'abc123', + 'something', + '' + ].join('\n')); + assertCursor(cursor, new Position(3, 1)); + }); + + model.dispose(); + }); }); suite('Editor Controller - Cursor Configuration', () => { @@ -2636,7 +2660,7 @@ suite('Editor Controller - Cursor Configuration', () => { '', ' }', ].join('\n')); - assertCursor(cursor, new Position(4, 1)); + assertCursor(cursor, new Position(5, 1)); }); model.dispose(); diff --git a/src/vs/editor/test/browser/testCommand.ts b/src/vs/editor/test/browser/testCommand.ts index ce33b94a913..8126f24735a 100644 --- a/src/vs/editor/test/browser/testCommand.ts +++ b/src/vs/editor/test/browser/testCommand.ts @@ -50,17 +50,19 @@ export function testCommand( export function getEditOperation(model: ITextModel, command: ICommand): IIdentifiedSingleEditOperation[] { let operations: IIdentifiedSingleEditOperation[] = []; let editOperationBuilder: IEditOperationBuilder = { - addEditOperation: (range: Range, text: string) => { + addEditOperation: (range: Range, text: string, forceMoveMarkers: boolean = false) => { operations.push({ range: range, - text: text + text: text, + forceMoveMarkers: forceMoveMarkers }); }, - addTrackedEditOperation: (range: Range, text: string) => { + addTrackedEditOperation: (range: Range, text: string, forceMoveMarkers: boolean = false) => { operations.push({ range: range, - text: text + text: text, + forceMoveMarkers: forceMoveMarkers }); }, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 3a6307fbbda..2c32863e855 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1906,14 +1906,14 @@ declare namespace monaco.editor { * @param range The range to replace (delete). May be empty to represent a simple insert. * @param text The text to replace with. May be null to represent a simple delete. */ - addEditOperation(range: Range, text: string | null): void; + addEditOperation(range: Range, text: string | null, forceMoveMarkers?: boolean): void; /** * Add a new edit operation (a replace operation). * The inverse edits will be accessible in `ICursorStateComputerData.getInverseEditOperations()` * @param range The range to replace (delete). May be empty to represent a simple insert. * @param text The text to replace with. May be null to represent a simple delete. */ - addTrackedEditOperation(range: Range, text: string | null): void; + addTrackedEditOperation(range: Range, text: string | null, forceMoveMarkers?: boolean): void; /** * Track `selection` when applying edit operations. * A best effort will be made to not grow/expand the selection. -- GitLab